1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
30 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 // Calculate base point and unit normal vector from plane equation
33 void Foam::plane::calcPntAndVec(const scalarList& C)
35 if (mag(C[0]) > VSMALL)
37 basePoint_ = vector((-C[3]/C[0]), 0, 0);
41 if (mag(C[1]) > VSMALL)
43 basePoint_ = vector(0, (-C[3]/C[1]), 0);
47 if (mag(C[2]) > VSMALL)
49 basePoint_ = vector(0, 0, (-C[3]/C[2]));
53 FatalErrorIn("void plane::calcPntAndVec(const scalarList&)")
54 << "At least one plane coefficient must have a value"
60 unitVector_ = vector(C[0], C[1], C[2]);
61 scalar magUnitVector(mag(unitVector_));
63 if (magUnitVector < VSMALL)
65 FatalErrorIn("void plane::calcPntAndVec(const scalarList&)")
66 << "Plane normal defined with zero length"
70 unitVector_ /= magUnitVector;
74 void Foam::plane::calcPntAndVec
81 basePoint_ = (point1 + point2 + point3)/3;
82 vector line12 = point1 - point2;
83 vector line23 = point2 - point3;
88 || mag(line23) < VSMALL
89 || mag(point3-point1) < VSMALL
94 "void plane::calcPntAndVec\n"
100 ) << "Bad points." << abort(FatalError);
103 unitVector_ = line12 ^ line23;
104 scalar magUnitVector(mag(unitVector_));
106 if (magUnitVector < VSMALL)
110 "void plane::calcPntAndVec\n"
116 ) << "Plane normal defined with zero length"
117 << abort(FatalError);
120 unitVector_ /= magUnitVector;
124 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
126 // Construct from normal vector through the origin
127 Foam::plane::plane(const vector& normalVector)
129 unitVector_(normalVector),
130 basePoint_(vector::zero)
134 // Construct from point and normal vector
135 Foam::plane::plane(const point& basePoint, const vector& normalVector)
137 unitVector_(normalVector),
138 basePoint_(basePoint)
140 scalar magUnitVector(mag(unitVector_));
142 if (magUnitVector > VSMALL)
144 unitVector_ /= magUnitVector;
148 FatalErrorIn("plane::plane(const point&, const vector&)")
149 << "plane normal has got zero length"
150 << abort(FatalError);
155 // Construct from plane equation
156 Foam::plane::plane(const scalarList& C)
162 // Construct from three points
170 calcPntAndVec(a, b, c);
174 // Construct from dictionary
175 Foam::plane::plane(const dictionary& dict)
177 unitVector_(vector::zero),
178 basePoint_(point::zero)
180 word planeType(dict.lookup("planeType"));
182 if (planeType == "planeEquation")
184 const dictionary& subDict = dict.subDict("planeEquationDict");
187 C[0] = readScalar(subDict.lookup("a"));
188 C[1] = readScalar(subDict.lookup("b"));
189 C[2] = readScalar(subDict.lookup("c"));
190 C[3] = readScalar(subDict.lookup("d"));
195 else if (planeType == "embeddedPoints")
197 const dictionary& subDict = dict.subDict("embeddedPoints");
199 point point1(subDict.lookup("point1"));
200 point point2(subDict.lookup("point2"));
201 point point3(subDict.lookup("point3"));
203 calcPntAndVec(point1, point2, point3);
205 else if (planeType == "pointAndNormal")
207 const dictionary& subDict = dict.subDict("pointAndNormalDict");
209 basePoint_ = subDict.lookup("basePoint");
210 unitVector_ = subDict.lookup("normalVector");
211 unitVector_ /= mag(unitVector_);
217 "plane::plane(const dictionary&)",
220 << "Invalid plane type: " << planeType
221 << abort(FatalIOError);
226 // Construct from Istream. Assumes point and normal vector.
227 Foam::plane::plane(Istream& is)
232 scalar magUnitVector(mag(unitVector_));
234 if (magUnitVector > VSMALL)
236 unitVector_ /= magUnitVector;
240 FatalErrorIn("plane::plane(Istream& is)")
241 << "plane normal has got zero length"
242 << abort(FatalError);
247 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
249 // Return plane normal vector
250 const Foam::vector& Foam::plane::normal() const
256 // Return plane base point
257 const Foam::point& Foam::plane::refPoint() const
263 // Return coefficcients for plane equation: ax + by + cz + d = 0
264 Foam::scalarList Foam::plane::planeCoeffs() const
268 scalar magX = mag(unitVector_.x());
269 scalar magY = mag(unitVector_.y());
270 scalar magZ = mag(unitVector_.z());
277 C[1] = unitVector_.y()/unitVector_.x();
278 C[2] = unitVector_.z()/unitVector_.x();
293 C[2] = unitVector_.z()/unitVector_.y();
303 C[3] = - C[0] * basePoint_.x()
304 - C[1] * basePoint_.y()
305 - C[2] * basePoint_.z();
311 // Return nearest point in the plane for the given point
312 Foam::point Foam::plane::nearestPoint(const point& p) const
314 return p - unitVector_*((p - basePoint_) & unitVector_);
318 // Return distance from the given point to the plane
319 Foam::scalar Foam::plane::distance(const point& p) const
321 return mag((p - basePoint_) & unitVector_);
325 // Cutting point for plane and line defined by origin and direction
326 Foam::scalar Foam::plane::normalIntersect
332 scalar denom = stabilise((dir & unitVector_), VSMALL);
334 return ((basePoint_ - pnt0) & unitVector_)/denom;
338 // Cutting line of two planes
339 Foam::plane::ray Foam::plane::planeIntersect(const plane& plane2) const
341 // Mathworld plane-plane intersection. Assume there is a point on the
342 // intersection line with z=0 and solve the two plane equations
343 // for that (now 2x2 equation in x and y)
344 // Better: use either z=0 or x=0 or y=0.
346 const vector& n1 = normal();
347 const vector& n2 = plane2.normal();
349 const point& p1 = refPoint();
350 const point& p2 = plane2.refPoint();
355 vector dir = n1 ^ n2;
357 // Determine zeroed out direction (can be x,y or z) by looking at which
358 // has the largest component in dir.
359 scalar magX = mag(dir.x());
360 scalar magY = mag(dir.y());
361 scalar magZ = mag(dir.z());
363 direction iZero, i1, i2;
399 pt[i1] = (n2[i2]*n1p1 - n1[i2]*n2p2) / (n1[i1]*n2[i2] - n2[i1]*n1[i2]);
400 pt[i2] = (n2[i1]*n1p1 - n1[i1]*n2p2) / (n1[i2]*n2[i1] - n1[i1]*n2[i2]);
406 // Cutting point of three planes
407 Foam::point Foam::plane::planePlaneIntersect
413 List<scalarList> pcs(3);
414 pcs[0]= planeCoeffs();
415 pcs[1]= plane2.planeCoeffs();
416 pcs[2]= plane3.planeCoeffs();
420 pcs[0][0],pcs[0][1],pcs[0][2],
421 pcs[1][0],pcs[1][1],pcs[1][2],
422 pcs[2][0],pcs[2][1],pcs[2][2]
425 vector b(pcs[0][3],pcs[1][3],pcs[2][3]);
427 return (inv(a) & (-b));
431 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
433 bool Foam::operator==(const plane& a, const plane& b)
435 if (a.basePoint_ == b.basePoint_ && a.unitVector_ == b.unitVector_)
445 bool Foam::operator!=(const plane& a, const plane& b)
451 // * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
453 Foam::Ostream& Foam::operator<<(Ostream& os, const plane& a)
455 os << a.unitVector_ << token::SPACE << a.basePoint_;
461 // ************************************************************************* //