27#ifndef EASY3D_CORE_PLANE_H
28#define EASY3D_CORE_PLANE_H
30#include <easy3d/core/vec.h>
31#include <easy3d/core/line.h>
32#include <easy3d/util/logging.h>
67 inline FT
a()
const {
return coeff_[0]; }
70 inline FT
b()
const {
return coeff_[1]; }
73 inline FT
c()
const {
return coeff_[2]; }
76 inline FT
d()
const {
return coeff_[3]; }
122 return (coeff_[0] * p.x + coeff_[1] * p.y + coeff_[2] * p.z + coeff_[3]);
168 const FT *
data()
const {
return coeff_; }
175 operator const FT *()
const {
return coeff_; }
179 operator FT *() {
return coeff_; }
186 template<
typename FT>
187 std::ostream &
operator<<(std::ostream &os,
const GenericPlane<FT> &plane);
189 template<
typename FT>
190 std::istream &
operator>>(std::istream &is, GenericPlane<FT> &plane);
193 template<
typename FT>
202 coeff_[3] = -(coeff_[0] * p1.x + coeff_[1] * p1.y + coeff_[2] * p1.z);
204 DLOG_IF(
length(n) < 1e-15, ERROR) <<
"degenerate plane constructed from 3 points:"
205 <<
"\t(" << p1 <<
")"
206 <<
"\t(" << p2 <<
")"
207 <<
"\t(" << p3 <<
")";
210 template<
typename FT>
217 coeff_[3] = -(coeff_[0] * p.x + coeff_[1] * p.y + coeff_[2] * p.z);
219 DLOG_IF(
length(nn) < 1e-15, ERROR) <<
"degenerate plane constructed from point ("
220 << p <<
") and normal (" << n <<
")";
224 template<
typename FT>
228 DLOG_IF(
length(n) < 1e-15, ERROR) <<
"degenerate plane with normal: (" << n <<
")";
233 template<
typename FT>
237 return Vector3(FT(1), FT(0), FT(0));
238 else if (coeff_[1] == 0)
239 return Vector3(FT(0), FT(1), FT(0));
240 else if (coeff_[2] == 0)
241 return Vector3(FT(0), FT(0), FT(1));
243 Vector3 base(-coeff_[1], coeff_[0], FT(0));
249 template<
typename FT>
256 template<
typename FT>
260 FT x =
dot(vec, base1());
261 FT y =
dot(vec, base2());
266 template<
typename FT>
269 return point() + base1() * p.x + base2() * p.y;
273 template<
typename FT>
276 Point3 p(FT(0), FT(0), FT(0));
277 if (std::abs(coeff_[0]) >= std::abs(coeff_[1]) && std::abs(coeff_[0]) >= std::abs(coeff_[2]))
278 p.x = -coeff_[3] / coeff_[0];
279 else if (std::abs(coeff_[1]) >= std::abs(coeff_[0]) && std::abs(coeff_[1]) >= std::abs(coeff_[2]))
280 p.y = -coeff_[3] / coeff_[1];
282 p.z = -coeff_[3] / coeff_[2];
301 template<
typename FT>
305 if (std::abs(v) < 1e-15)
308 return (v > 0.0 ? 1 : -1);
312 template<
typename FT>
320 FT num = coeff_[0] * p.x + coeff_[1] * p.y + coeff_[2] * p.z + coeff_[3];
321 FT den = coeff_[0] * coeff_[0] + coeff_[1] * coeff_[1] + coeff_[2] * coeff_[2];
322 FT lambda = num / den;
324 FT x = p.x - lambda * coeff_[0];
325 FT y = p.y - lambda * coeff_[1];
326 FT z = p.z - lambda * coeff_[2];
331 template<
typename FT>
335 return (v * v) / (coeff_[0] * coeff_[0] + coeff_[1] * coeff_[1] + coeff_[2] * coeff_[2]);
339 template<
typename FT>
343 FT c =
dot(dir, normal());
344 if (std::abs(c) < 1e-15)
351 template<
typename FT>
355 FT c =
dot(dir, normal());
356 if (std::abs(c) < 1e-15)
362 FT t = -(coeff_[0] * p0.x + coeff_[1] * p0.y + coeff_[2] * p0.z + coeff_[3]) /
363 (coeff_[0] * dir.x + coeff_[1] * dir.y + coeff_[2] * dir.z);
369 template<
typename FT>
374 if ((ss == 1 && st == -1) || (ss == -1 && st == 1))
376 else if (ss == 0 || st == 0)
383 template<
typename FT>
388 if ((ss == 1 && st == -1) || (ss == -1 && st == 1)) {
392 LOG(ERROR) <<
"fatal error. Should have intersection";
399 }
else if (st == 0) {
410 template<
typename FT>
413 const FT &a = coeff_[0];
414 const FT &b = coeff_[1];
415 const FT &c = coeff_[2];
416 const FT &d = coeff_[3];
417 const FT &p = another.coeff_[0];
418 const FT &q = another.coeff_[1];
419 const FT &r = another.coeff_[2];
420 const FT &s = another.coeff_[3];
422 FT
det = a * q - p * b;
433 if (a != 0 || p != 0)
434 return (a * s == p * d);
435 if (b != 0 || q != 0)
436 return (b * s == q * d);
437 if (c != 0 || r != 0)
438 return (c * s == r * d);
444 template<
typename FT>
447 const FT &a = coeff_[0];
448 const FT &b = coeff_[1];
449 const FT &c = coeff_[2];
450 const FT &d = coeff_[3];
451 const FT &p = another.coeff_[0];
452 const FT &q = another.coeff_[1];
453 const FT &r = another.coeff_[2];
454 const FT &s = another.coeff_[3];
456 FT
det = a * q - p * b;
458 const Point3 pt((b * s - d * q) /
det, (p * d - a * s) /
det, 0);
459 const Vector3 dir((b * r - c * q), (p * c - a * r),
det);
465 const Point3 pt((c * s - d * r) /
det, 0, (p * d - a * s) /
det);
466 const Vector3 dir((c * q - b * r),
det, (p * b - a * q));
472 const Point3 pt(0, (c * s - d * r) /
det, (d * q - b * s) /
det);
473 const Vector3 dir(
det, (c * p - a * r), (a * q - b * p));
484 template<
typename FT>
487 return os << plane[0] <<
' ' << plane[1] <<
' ' << plane[2] <<
' ' << plane[3];
491 template<
typename FT>
494 return is >> plane[0] >> plane[1] >> plane[2] >> plane[3];
507 template<
typename FT>
A generic line representation, which supports both 2D and 3D lines.
Definition: line.h:40
static GenericLine from_two_points(const Point &p, const Point &q)
Constructs a line from two points p and q.
Definition: line.h:50
const Vector & direction() const
Returns the direction of a line.
Definition: line.h:62
const Point & point() const
Returns an arbitrary point on a line.
Definition: line.h:65
static GenericLine from_point_and_direction(const Point &p, const Vector &dir)
Constructs a line from a point p and its direction dir.
Definition: line.h:48
A 3D Plane of equation a*x + b*y + c*z + d = 0.
Definition: plane.h:41
bool intersect(const Line3 &line, Point3 &p) const
Tests if a line intersects with this plane. Returns true if they do intersect. In this case,...
Definition: plane.h:353
GenericPlane(const Point3 &p1, const Point3 &p2, const Point3 &p3)
Constructs a plane from three points p1, p2, and p3.
Definition: plane.h:195
FT * data()
Returns the memory address of the coefficients.
Definition: plane.h:171
FT squared_distance(const Point3 &p) const
Computes the squared distance of a point p to this plane.
Definition: plane.h:333
FT value(const Point3 &p) const
Evaluates the plane (i.e., computes the value of a * x + b * y + c * z + d) for the given point p.
Definition: plane.h:121
FT c() const
Returns plane equation parameter c.
Definition: plane.h:73
Vector3 base2() const
Returns the second ortho-base defined on this plane.
Definition: plane.h:251
bool intersect(const thisclass &another, Line3 &line) const
Tests if this plane intersects with another plane. Returns true if they do intersect....
Definition: plane.h:446
Point2 to_2d(const Point3 &p) const
Converts a 3D point into a 2D point relative to the local coordinate system defined by the three orth...
Definition: plane.h:258
FT b() const
Returns plane equation parameter b.
Definition: plane.h:70
bool intersect(const thisclass &another) const
Tests if this plane intersects with another plane. Returns true if they do intersect and false if the...
Definition: plane.h:412
int orient(const Point3 &p) const
Determines the relative orientation of a point with respect to this plane. The return value is one of...
Definition: plane.h:303
bool intersect(const Point3 &s, const Point3 &t) const
Tests if a line segment (given by its two end points s and t) intersects with this plane....
Definition: plane.h:371
bool intersect(const Line3 &line) const
Tests if a line intersects with this plane. Returns true if they do intersect. Otherwise,...
Definition: plane.h:341
FT a() const
Returns plane equation parameter a.
Definition: plane.h:67
const FT * data() const
Returns the constant memory address of the coefficients.
Definition: plane.h:168
const FT & operator[](size_t idx) const
Returns the idx_th const parameter of the plane equation.
Definition: plane.h:85
Vector3 base1() const
Returns the first ortho-base defined on this plane.
Definition: plane.h:235
FT & operator[](size_t idx)
Returns the idx_th parameter of the plane equation.
Definition: plane.h:79
bool intersect(const Point3 &s, const Point3 &t, Point3 &p) const
Tests if a line segment (given by its two end points s and t) intersects with this plane....
Definition: plane.h:385
Point3 projection(const Point3 &p) const
The projection of a point p on this plane.
Definition: plane.h:314
GenericPlane(FT a, FT b, FT c, FT d)
Constructs a plane from its equation parameters a, b, c, and d.
Definition: plane.h:57
Vector3 normal() const
Returns the normal of the plane.
Definition: plane.h:226
GenericPlane(const Point3 &p, const Vector3 &n)
Constructs a plane from a point p and the plane normal n.
Definition: plane.h:212
Point3 to_3d(const Point2 &p) const
Converts a 2D point in the local coordinate system defined by the three orthogonal vectors base1(),...
Definition: plane.h:268
Point3 point() const
Returns a point lying on this plane.
Definition: plane.h:275
FT d() const
Returns plane equation parameter d.
Definition: plane.h:76
Base class for vector types. It provides generic functionality for N dimensional vectors.
Definition: vec.h:34
bool intersect(const GenericPlane< FT > &plane1, const GenericPlane< FT > &plane2, const GenericPlane< FT > &plane3, typename GenericPlane< FT >::Point3 &point)
Definition: plane.h:509
Definition: collider.cpp:182
std::istream & operator>>(std::istream &is, GenericLine< DIM, FT > &line)
Definition: line.h:133
T length(const Vec< N, T > &v)
Computes the length/magnitude of a vector.
Definition: vec.h:289
std::ostream & operator<<(std::ostream &os, Graph::Vertex v)
Definition: graph.h:920
T det(const Vec< 2, T > &v1, const Vec< 2, T > &v2)
Compute the determinant of the 2x2 matrix formed by the two 2D vectors as the two rows.
Definition: vec.h:405
Vec< 3, T > cross(const Vec< 3, T > &v1, const Vec< 3, T > &v2)
Compute the cross product of two 3D vectors.
Definition: vec.h:534
FT dot(const std::vector< FT > &, const std::vector< FT > &)
Inner product for vectors.
Definition: matrix.h:1803
Vec< N, T > normalize(const Vec< N, T > &v)
Computes and returns the normalized vector (Note: the input vector is not modified).
Definition: vec.h:299