source: trunk/src/core2/RpFieldRect3D.cc @ 4952

Last change on this file since 4952 was 3177, checked in by mmc, 12 years ago

Updated all of the copyright notices to reference the transfer to
the new HUBzero Foundation, LLC.

File size: 4.2 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-2012  HUBzero Foundation, LLC
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    _vmin(NAN),
23    _vmax(NAN),
24    _meshPtr(NULL),
25    _counter(0)
26{
27}
28
29FieldRect3D::FieldRect3D(const Mesh1D& xg, const Mesh1D& yg, const Mesh1D& zg)
30  : _valuelist(),
31    _vmin(NAN),
32    _vmax(NAN),
33    _meshPtr(NULL),
34    _counter(0)
35{
36    _meshPtr = Ptr<MeshRect3D>( new MeshRect3D(xg,yg,zg) );
37    int npts = xg.size()*yg.size()*zg.size();
38    _valuelist.reserve(npts);
39}
40
41FieldRect3D::FieldRect3D(const FieldRect3D& field)
42  : _valuelist(field._valuelist),
43    _vmin(field._vmin),
44    _vmax(field._vmax),
45    _meshPtr(field._meshPtr),
46    _counter(field._counter)
47{
48}
49
50FieldRect3D&
51FieldRect3D::operator=(const FieldRect3D& field)
52{
53    _valuelist = field._valuelist;
54    _vmin = field._vmin;
55    _vmax = field._vmax;
56    _meshPtr = field._meshPtr;
57    _counter = field._counter;
58    return *this;
59}
60
61FieldRect3D::~FieldRect3D()
62{
63}
64
65int
66FieldRect3D::size(Axis which) const
67{
68    if (!_meshPtr.isNull()) {
69        return _meshPtr->size(which);
70    }
71    return 0;
72}
73
74Node1D&
75FieldRect3D::atNode(Axis which, int pos)
76{
77    static Node1D null(0.0);
78
79    if (!_meshPtr.isNull()) {
80        return _meshPtr->at(which, pos);
81    }
82    return null;
83}
84
85double
86FieldRect3D::rangeMin(Axis which) const
87{
88    if (!_meshPtr.isNull()) {
89        return _meshPtr->rangeMin(which);
90    }
91    return 0.0;
92}
93
94double
95FieldRect3D::rangeMax(Axis which) const
96{
97    if (!_meshPtr.isNull()) {
98        return _meshPtr->rangeMax(which);
99    }
100    return 0.0;
101}
102
103FieldRect3D&
104FieldRect3D::define(int nodeId, double f)
105{
106    if (_valuelist.size() < (unsigned int)(nodeId+1)) {
107        _valuelist.resize((unsigned int)(nodeId+1), NAN);
108    }
109    _valuelist[nodeId] = f;
110
111    if (isnan(_vmin) || isnan(_vmax)) {
112        _vmin = _vmax = f;
113    } else {
114        if (f < _vmin) { _vmin = f; }
115        if (f > _vmax) { _vmax = f; }
116    }
117    return *this;
118}
119
120double
121FieldRect3D::value(double x, double y, double z, double outside) const
122{
123    double f0, f1, fy0, fy1, fz0, fz1;
124
125    if (!_meshPtr.isNull()) {
126        CellRect3D cell = _meshPtr->locate(Node3D(x,y,z));
127
128        // outside the defined data? then return the outside value
129        if (cell.isOutside()) {
130            return outside;
131        }
132
133        // yuck! brute force...
134        // interpolate x @ y0,z0
135        f0 = _valuelist[cell.nodeId(0)];
136        f1 = _valuelist[cell.nodeId(1)];
137        fy0 = _interpolate(cell.x(0),f0, cell.x(1),f1, x);
138
139        // interpolate x @ y1,z0
140        f0 = _valuelist[cell.nodeId(2)];
141        f1 = _valuelist[cell.nodeId(3)];
142        fy1 = _interpolate(cell.x(2),f0, cell.x(3),f1, x);
143
144        // interpolate y @ z0
145        fz0 = _interpolate(cell.y(0),fy0, cell.y(2),fy1, y);
146
147        // interpolate x @ y0,z1
148        f0 = _valuelist[cell.nodeId(4)];
149        f1 = _valuelist[cell.nodeId(5)];
150        fy0 = _interpolate(cell.x(4),f0, cell.x(5),f1, x);
151
152        // interpolate x @ y1,z1
153        f0 = _valuelist[cell.nodeId(6)];
154        f1 = _valuelist[cell.nodeId(7)];
155        fy1 = _interpolate(cell.x(6),f0, cell.x(7),f1, x);
156
157        // interpolate y @ z1
158        fz1 = _interpolate(cell.y(4),fy0, cell.y(6),fy1, y);
159
160        // interpolate z
161        return _interpolate(cell.z(0),fz0, cell.z(4),fz1, z);
162    }
163    return outside;
164}
165
166double
167FieldRect3D::valueMin() const
168{
169    return _vmin;
170}
171
172double
173FieldRect3D::valueMax() const
174{
175    return _vmax;
176}
177
178double
179FieldRect3D::_interpolate(double x0, double y0, double x1, double y1,
180    double x) const
181{
182    double dx = x1-x0;
183    if (dx == 0.0) {
184        return 0.5*(y0+y1);
185    }
186    return (y1-y0)*((x-x0)/dx) + y0;
187}
188
Note: See TracBrowser for help on using the repository browser.