source: trunk/src2/core/RpFieldRect3D.cc @ 371

Last change on this file since 371 was 370, checked in by mmc, 19 years ago

Added support for triangular and prismatic meshes.

Serialization sort of works. Needs better treatment of pointers for
classes derived from Rappture::Serializable.

File size: 3.7 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 *  Rappture::FieldRect3D
4 *    This is a continuous, linear function defined by a series of
5 *    points on a 3D structured mesh.  It's a scalar field defined
6 *    in 3D space.
7 *
8 * ======================================================================
9 *  AUTHOR:  Michael McLennan, Purdue University
10 *  Copyright (c) 2004-2006  Purdue Research Foundation
11 *
12 *  See the file "license.terms" for information on usage and
13 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14 * ======================================================================
15 */
16#include "RpFieldRect3D.h"
17
18using namespace Rappture;
19
20FieldRect3D::FieldRect3D()
21  : _valuelist(),
22    _meshPtr(NULL),
23    _counter(0)
24{
25}
26
27FieldRect3D::FieldRect3D(const Mesh1D& xg, const Mesh1D& yg, const Mesh1D& zg)
28  : _valuelist(),
29    _meshPtr(NULL),
30    _counter(0)
31{
32    _meshPtr = Ptr<MeshRect3D>( new MeshRect3D(xg,yg,zg) );
33    int npts = xg.size()*yg.size()*zg.size();
34    _valuelist.reserve(npts);
35}
36
37FieldRect3D::FieldRect3D(const FieldRect3D& field)
38  : _valuelist(field._valuelist),
39    _meshPtr(field._meshPtr),
40    _counter(field._counter)
41{
42}
43
44FieldRect3D&
45FieldRect3D::operator=(const FieldRect3D& field)
46{
47    _valuelist = field._valuelist;
48    _meshPtr = field._meshPtr;
49    _counter = field._counter;
50    return *this;
51}
52
53FieldRect3D::~FieldRect3D()
54{
55}
56
57int
58FieldRect3D::size(Axis which) const
59{
60    if (!_meshPtr.isNull()) {
61        return _meshPtr->size(which);
62    }
63    return 0;
64}
65
66Node1D&
67FieldRect3D::atNode(Axis which, int pos)
68{
69    static Node1D null(0.0);
70
71    if (!_meshPtr.isNull()) {
72        return _meshPtr->at(which, pos);
73    }
74    return null;
75}
76
77double
78FieldRect3D::rangeMin(Axis which) const
79{
80    if (!_meshPtr.isNull()) {
81        return _meshPtr->rangeMin(which);
82    }
83    return 0.0;
84}
85
86double
87FieldRect3D::rangeMax(Axis which) const
88{
89    if (!_meshPtr.isNull()) {
90        return _meshPtr->rangeMax(which);
91    }
92    return 0.0;
93}
94
95FieldRect3D&
96FieldRect3D::define(int nodeId, double f)
97{
98    _valuelist[nodeId] = f;
99    return *this;
100}
101
102double
103FieldRect3D::value(double x, double y, double z, double outside) const
104{
105    double f0, f1, fy0, fy1, fz0, fz1;
106
107    if (!_meshPtr.isNull()) {
108        CellRect3D cell = _meshPtr->locate(Node3D(x,y,z));
109
110        // outside the defined data? then return the outside value
111        if (cell.isOutside()) {
112            return outside;
113        }
114
115        // yuck! brute force...
116        // interpolate x @ y0,z0
117        f0 = _valuelist[cell.nodeId(0)];
118        f1 = _valuelist[cell.nodeId(1)];
119        fy0 = _interpolate(cell.x(0),f0, cell.x(1),f1, x);
120
121        // interpolate x @ y1,z0
122        f0 = _valuelist[cell.nodeId(2)];
123        f1 = _valuelist[cell.nodeId(3)];
124        fy1 = _interpolate(cell.x(2),f0, cell.x(3),f1, x);
125
126        // interpolate y @ z0
127        fz0 = _interpolate(cell.y(0),fy0, cell.y(2),fy1, y);
128
129        // interpolate x @ y0,z1
130        f0 = _valuelist[cell.nodeId(4)];
131        f1 = _valuelist[cell.nodeId(5)];
132        fy0 = _interpolate(cell.x(4),f0, cell.x(5),f1, x);
133
134        // interpolate x @ y1,z1
135        f0 = _valuelist[cell.nodeId(6)];
136        f1 = _valuelist[cell.nodeId(7)];
137        fy1 = _interpolate(cell.x(6),f0, cell.x(7),f1, x);
138
139        // interpolate y @ z1
140        fz1 = _interpolate(cell.y(4),fy0, cell.y(6),fy1, y);
141
142        // interpolate z
143        return _interpolate(cell.z(0),fz0, cell.z(4),fz1, z);
144    }
145    return outside;
146}
147
148double
149FieldRect3D::_interpolate(double x0, double y0, double x1, double y1,
150    double x) const
151{
152    double dx = x1-x0;
153    if (dx == 0.0) {
154        return 0.5*(y0+y1);
155    }
156    return (y1-y0)*((x-x0)/dx) + y0;
157}
158
Note: See TracBrowser for help on using the repository browser.