Graphite  Version 3
An experimental 3D geometry processing program
geometry.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2000-2022 Inria
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * * Neither the name of the ALICE Project-Team nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * Contact: Bruno Levy
30  *
31  * https://www.inria.fr/fr/bruno-levy
32  *
33  * Inria,
34  * Domaine de Voluceau,
35  * 78150 Le Chesnay - Rocquencourt
36  * FRANCE
37  *
38  */
39 
40 #ifndef GEOGRAM_BASIC_GEOMETRY
41 #define GEOGRAM_BASIC_GEOMETRY
42 
43 #include <geogram/basic/common.h>
44 #include <geogram/basic/matrix.h>
45 
51 namespace GEO {
52 
53  /************************************************************************/
54 
60 
66 
72 
79 
86 
93 
94 
101 
108 
115 
116 
122 
128 
134 
135  /************************************************************************/
136 
142  inline double det(const mat2& M) {
143  return det2x2(
144  M(0,0), M(0,1),
145  M(1,0), M(1,1)
146  );
147  }
148 
154  inline double det(const mat3& M) {
155  return det3x3(
156  M(0,0), M(0,1), M(0,2),
157  M(1,0), M(1,1), M(1,2),
158  M(2,0), M(2,1), M(2,2)
159  );
160  }
161 
167  inline double det(const mat4& M) {
168  return det4x4(
169  M(0,0), M(0,1), M(0,2), M(0,3),
170  M(1,0), M(1,1), M(1,2), M(1,3),
171  M(2,0), M(2,1), M(2,2), M(2,3),
172  M(3,0), M(3,1), M(3,2), M(3,3)
173  );
174  }
175 
176  /************************************************************************/
177 
181  namespace Geom {
182 
189  inline vec3 barycenter(const vec3& p1, const vec3& p2) {
190  return vec3(
191  0.5 * (p1.x + p2.x),
192  0.5 * (p1.y + p2.y),
193  0.5 * (p1.z + p2.z)
194  );
195  }
196 
203  inline vec2 barycenter(const vec2& p1, const vec2& p2) {
204  return vec2(
205  0.5 * (p1.x + p2.x),
206  0.5 * (p1.y + p2.y)
207  );
208  }
209 
217  inline vec3 barycenter(
218  const vec3& p1, const vec3& p2, const vec3& p3
219  ) {
220  return vec3(
221  (p1.x + p2.x + p3.x) / 3.0,
222  (p1.y + p2.y + p3.y) / 3.0,
223  (p1.z + p2.z + p3.z) / 3.0
224  );
225  }
226 
234  inline vec2 barycenter(
235  const vec2& p1, const vec2& p2, const vec2& p3
236  ) {
237  return vec2(
238  (p1.x + p2.x + p3.x) / 3.0,
239  (p1.y + p2.y + p3.y) / 3.0
240  );
241  }
242 
249  inline double cos_angle(const vec3& a, const vec3& b) {
250  double lab = ::sqrt(length2(a)*length2(b));
251  double result = (lab > 1e-50) ? (dot(a, b) / lab) : 1.0;
252  // Numerical precision problem may occur, and generate
253  // normalized dot products that are outside the valid
254  // range of acos.
255  geo_clamp(result, -1.0, 1.0);
256  return result;
257  }
258 
266  inline double angle(const vec3& a, const vec3& b) {
267  return ::acos(cos_angle(a, b));
268  }
269 
276  inline double cos_angle(const vec2& a, const vec2& b) {
277  double lab = ::sqrt(length2(a)*length2(b));
278  double result = (lab > 1e-20) ? (dot(a, b) / lab) : 1.0;
279  // Numerical precision problem may occur, and generate
280  // normalized dot products that are outside the valid
281  // range of acos.
282  geo_clamp(result, -1.0, 1.0);
283  return result;
284  }
285 
292  inline double det(const vec2& a, const vec2& b) {
293  return a.x * b.y - a.y * b.x;
294  }
295 
303  inline double angle(const vec2& a, const vec2& b) {
304  return det(a, b) > 0 ?
305  ::acos(cos_angle(a, b)) :
306  -::acos(cos_angle(a, b));
307  }
308 
316  const vec3& p1, const vec3& p2, const vec3& p3
317  ) {
318  return cross(p2 - p1, p3 - p1);
319  }
320 
326  inline double triangle_area_3d(
327  const double* p1, const double* p2, const double* p3
328  ) {
329  double Ux = p2[0] - p1[0];
330  double Uy = p2[1] - p1[1];
331  double Uz = p2[2] - p1[2];
332 
333  double Vx = p3[0] - p1[0];
334  double Vy = p3[1] - p1[1];
335  double Vz = p3[2] - p1[2];
336 
337  double Nx = Uy*Vz - Uz*Vy;
338  double Ny = Uz*Vx - Ux*Vz;
339  double Nz = Ux*Vy - Uy*Vx;
340  return 0.5 * ::sqrt(Nx*Nx+Ny*Ny+Nz*Nz);
341  }
342 
348  inline double triangle_area(
349  const vec3& p1, const vec3& p2, const vec3& p3
350  ) {
351  return triangle_area_3d(p1.data(), p2.data(), p3.data());
352  }
353 
362  inline double triangle_signed_area_2d(
363  const double* p1, const double* p2, const double* p3
364  ) {
365  double a = p2[0]-p1[0];
366  double b = p3[0]-p1[0];
367  double c = p2[1]-p1[1];
368  double d = p3[1]-p1[1];
369  return 0.5*(a*d-b*c);
370  }
371 
380  inline double triangle_signed_area(
381  const vec2& p1, const vec2& p2, const vec2& p3
382  ) {
383  return 0.5 * det(p2 - p1, p3 - p1);
384  }
385 
393  inline double triangle_area(
394  const vec2& p1, const vec2& p2, const vec2& p3
395  ) {
396  return ::fabs(triangle_signed_area(p1, p2, p3));
397  }
398 
406  inline double triangle_area_2d(
407  const double* p1, const double* p2, const double* p3
408  ) {
409  return ::fabs(triangle_signed_area_2d(p1,p2,p3));
410  }
411 
421  const vec2& p1, const vec2& p2, const vec2& p3
422  );
423 
429  inline bool has_nan(const vec3& v) {
430  return
431  Numeric::is_nan(v.x) ||
432  Numeric::is_nan(v.y) ||
433  Numeric::is_nan(v.z);
434  }
435 
441  inline bool has_nan(const vec2& v) {
442  return
443  Numeric::is_nan(v.x) ||
444  Numeric::is_nan(v.y);
445  }
446 
452  vec3 GEOGRAM_API perpendicular(const vec3& V);
453 
463  inline double tetra_signed_volume(
464  const vec3& p1, const vec3& p2,
465  const vec3& p3, const vec3& p4
466  ) {
467  return dot(p2 - p1, cross(p3 - p1, p4 - p1)) / 6.0;
468  }
469 
479  inline double tetra_signed_volume(
480  const double* p1, const double* p2,
481  const double* p3, const double* p4
482  ) {
483  return tetra_signed_volume(
484  *reinterpret_cast<const vec3*>(p1),
485  *reinterpret_cast<const vec3*>(p2),
486  *reinterpret_cast<const vec3*>(p3),
487  *reinterpret_cast<const vec3*>(p4)
488  );
489  }
490 
500  inline double tetra_volume(
501  const vec3& p1, const vec3& p2,
502  const vec3& p3, const vec3& p4
503  ) {
504  return ::fabs(tetra_signed_volume(p1, p2, p3, p4));
505  }
506 
518  const vec3& p1, const vec3& p2,
519  const vec3& p3, const vec3& p4
520  );
521 
534  inline void triangle_centroid(
535  const vec3& p, const vec3& q, const vec3& r,
536  double a, double b, double c,
537  vec3& Vg, double& V
538  ) {
539  double abc = a + b + c;
540  double area = Geom::triangle_area(p, q, r);
541  V = area / 3.0 * abc;
542  double wp = a + abc;
543  double wq = b + abc;
544  double wr = c + abc;
545  double s = area / 12.0;
546  Vg.x = s * (wp * p.x + wq * q.x + wr * r.x);
547  Vg.y = s * (wp * p.y + wq * q.y + wr * r.y);
548  Vg.z = s * (wp * p.z + wq * q.z + wr * r.z);
549  }
550 
563  inline double triangle_mass(
564  const vec3& p, const vec3& q, const vec3& r,
565  double a, double b, double c
566  ) {
567  return Geom::triangle_area(p, q, r) / 3.0 * (
568  sqrt(::fabs(a)) + sqrt(::fabs(b)) + sqrt(::fabs(c))
569  );
570  }
571 
583  const vec3& p1,
584  const vec3& p2,
585  const vec3& p3
586  ) {
587  double s = Numeric::random_float64();
588  double t = Numeric::random_float64();
589  if(s + t > 1) {
590  s = 1.0 - s;
591  t = 1.0 - t;
592  }
593  double u = 1.0 - s - t;
594  return vec3(
595  u * p1.x + s * p2.x + t * p3.x,
596  u * p1.y + s * p2.y + t * p3.y,
597  u * p1.z + s * p2.z + t * p3.z
598  );
599  }
600  }
601 
607  struct Plane {
608 
615  Plane(const vec3& p1, const vec3& p2, const vec3& p3) {
616  vec3 n = cross(p2 - p1, p3 - p1);
617  a = n.x;
618  b = n.y;
619  c = n.z;
620  d = -(a * p1.x + b * p1.y + c * p1.z);
621  }
622 
629  Plane(const vec3& p, const vec3& n) {
630  a = n.x;
631  b = n.y;
632  c = n.z;
633  d = -(a * p.x + b * p.y + c * p.z);
634  }
635 
640  double a_in, double b_in, double c_in, double d_in
641  ) :
642  a(a_in),
643  b(b_in),
644  c(c_in),
645  d(d_in) {
646  }
647 
651  Plane() {
652  }
653 
657  vec3 normal() const {
658  return vec3(a, b, c);
659  }
660 
661  double a, b, c, d;
662  };
663 
664  /*******************************************************************/
665 
669  class Box {
670  public:
671  double xyz_min[3];
672  double xyz_max[3];
673 
679  bool contains(const vec3& b) const {
680  for(coord_index_t c = 0; c < 3; ++c) {
681  if(b[c] < xyz_min[c]) {
682  return false;
683  }
684  if(b[c] > xyz_max[c]) {
685  return false;
686  }
687  }
688  return true;
689  }
690  };
691 
692  typedef Box Box3d;
693 
701  inline bool bboxes_overlap(const Box& B1, const Box& B2) {
702  for(coord_index_t c = 0; c < 3; ++c) {
703  if(B1.xyz_max[c] < B2.xyz_min[c]) {
704  return false;
705  }
706  if(B1.xyz_min[c] > B2.xyz_max[c]) {
707  return false;
708  }
709  }
710  return true;
711  }
712 
720  inline void bbox_union(Box& target, const Box& B1, const Box& B2) {
721  for(coord_index_t c = 0; c < 3; ++c) {
722  target.xyz_min[c] = std::min(B1.xyz_min[c], B2.xyz_min[c]);
723  target.xyz_max[c] = std::max(B1.xyz_max[c], B2.xyz_max[c]);
724  }
725  }
726 
727  /*******************************************************************/
728 
732  class Box2d {
733  public:
734  double xy_min[2];
735  double xy_max[2];
736 
742  bool contains(const vec2& b) const {
743  for(coord_index_t c = 0; c < 2; ++c) {
744  if(b[c] < xy_min[c]) {
745  return false;
746  }
747  if(b[c] > xy_max[c]) {
748  return false;
749  }
750  }
751  return true;
752  }
753  };
754 
755 
763  inline bool bboxes_overlap(const Box2d& B1, const Box2d& B2) {
764  for(coord_index_t c = 0; c < 2; ++c) {
765  if(B1.xy_max[c] < B2.xy_min[c]) {
766  return false;
767  }
768  if(B1.xy_min[c] > B2.xy_max[c]) {
769  return false;
770  }
771  }
772  return true;
773  }
774 
782  inline void bbox_union(Box2d& target, const Box2d& B1, const Box2d& B2) {
783  for(coord_index_t c = 0; c < 2; ++c) {
784  target.xy_min[c] = std::min(B1.xy_min[c], B2.xy_min[c]);
785  target.xy_max[c] = std::max(B1.xy_max[c], B2.xy_max[c]);
786  }
787  }
788 
789  /*******************************************************************/
790 
804  template <class FT> vecng<3,FT> transform_vector(
805  const vecng<3,FT>& v,
806  const Matrix<4,FT>& m
807  ){
808  index_t i,j ;
809  FT result[4] ;
810 
811  for(i=0; i<4; i++) {
812  result[i] = 0 ;
813  }
814  for(i=0; i<4; i++) {
815  for(j=0; j<3; j++) {
816  result[i] += v[j] * m(j,i) ;
817  }
818  }
819 
820  return vecng<3,FT>(
821  result[0], result[1], result[2]
822  ) ;
823  }
824 
840  template <class FT> vecng<3,FT> transform_point(
841  const vecng<3,FT>& v,
842  const Matrix<4,FT>& m
843  ){
844  index_t i,j ;
845  FT result[4] ;
846 
847  for(i=0; i<4; i++) {
848  result[i] = 0 ;
849  }
850  for(i=0; i<4; i++) {
851  for(j=0; j<3; j++) {
852  result[i] += v[j] * m(j,i) ;
853  }
854  result[i] += m(3,i);
855  }
856 
857  return vecng<3,FT>(
858  result[0] / result[3],
859  result[1] / result[3],
860  result[2] / result[3]
861  ) ;
862  }
863 
864 
880  template <class FT> vecng<3,FT> transform_point(
881  const Matrix<4,FT>& m,
882  const vecng<3,FT>& v
883  ){
884  index_t i,j ;
885  FT result[4] ;
886 
887  for(i=0; i<4; i++) {
888  result[i] = 0 ;
889  }
890  for(i=0; i<4; i++) {
891  for(j=0; j<3; j++) {
892  result[i] += v[j] * m(i,j) ;
893  }
894  result[i] += m(i,3);
895  }
896 
897  return vecng<3,FT>(
898  result[0] / result[3],
899  result[1] / result[3],
900  result[2] / result[3]
901  ) ;
902  }
903 
914  template <class FT> vecng<4,FT> transform_vector(
915  const vecng<4,FT>& v,
916  const Matrix<4,FT>& m
917  ) {
918  index_t i,j ;
919  FT res[4] = {FT(0), FT(0), FT(0), FT(0)};
920 
921  for(i=0; i<4; i++) {
922  for(j=0; j<4; j++) {
923  res[i] += v[j] * m(j,i) ;
924  }
925  }
926 
927  return vecng<4,FT>(res[0], res[1], res[2], res[3]) ;
928  }
929 
930  /******************************************************************/
931 
941  mat4 result;
942  result.load_identity();
943  result(3,0) = T.x;
944  result(3,1) = T.y;
945  result(3,2) = T.z;
946  return result;
947  }
948 
957  inline mat4 create_scaling_matrix(double s) {
958  mat4 result;
959  result.load_identity();
960  result(0,0) = s;
961  result(1,1) = s;
962  result(2,2) = s;
963  return result;
964  }
965 
966  /******************************************************************/
967 
971  struct Ray {
977  Ray(vec3 O, vec3 D) : origin(O), direction(D) {
978  }
982  Ray() {
983  }
984  vec3 origin;
985  vec3 direction;
986  };
987 
988  /******************************************************************/
989 
990 }
991 
992 #endif
Axis-aligned bounding box.
Definition: geometry.h:732
bool contains(const vec2 &b) const
Tests whether a box contains a point.
Definition: geometry.h:742
Axis-aligned bounding box.
Definition: geometry.h:669
bool contains(const vec3 &b) const
Tests whether a box contains a point.
Definition: geometry.h:679
A matrix type.
Definition: matrix.h:66
void load_identity()
Sets the matrix to identity.
Definition: matrix.h:145
T * data()
Gets modifiable vector data.
Definition: vecg.h:161
Common include file, providing basic definitions. Should be included before anything else by all head...
Generic matrix type.
double det(const vec2 &a, const vec2 &b)
Computes the determinant of two vectors.
Definition: geometry.h:292
double triangle_signed_area(const vec2 &p1, const vec2 &p2, const vec2 &p3)
Computes the area of a 2d triangle.
Definition: geometry.h:380
vec3 tetra_circum_center(const vec3 &p1, const vec3 &p2, const vec3 &p3, const vec3 &p4)
Computes the center of the circumscribed sphere of 3d tetrahedron.
vec3 random_point_in_triangle(const vec3 &p1, const vec3 &p2, const vec3 &p3)
Generates a random point in a 3d triangle.
Definition: geometry.h:582
double tetra_volume(const vec3 &p1, const vec3 &p2, const vec3 &p3, const vec3 &p4)
Computes the volume of a 3d tetrahedron.
Definition: geometry.h:500
vec3 perpendicular(const vec3 &V)
Computes a 3d vector orthogonal to another one.
vec3 triangle_normal(const vec3 &p1, const vec3 &p2, const vec3 &p3)
Computes the normal of a 3d triangle.
Definition: geometry.h:315
double triangle_mass(const vec3 &p, const vec3 &q, const vec3 &r, double a, double b, double c)
Computes the mass of a 3d triangle with weighted points.
Definition: geometry.h:563
double cos_angle(const vec3 &a, const vec3 &b)
Computes the cosine of the angle between two 3d vectors.
Definition: geometry.h:249
double triangle_area(const vec3 &p1, const vec3 &p2, const vec3 &p3)
Computes the area of a 3d triangle.
Definition: geometry.h:348
double triangle_signed_area_2d(const double *p1, const double *p2, const double *p3)
Computes the area of a 2d triangle.
Definition: geometry.h:362
void triangle_centroid(const vec3 &p, const vec3 &q, const vec3 &r, double a, double b, double c, vec3 &Vg, double &V)
Computes the centroid of a 3d triangle with weighted points.
Definition: geometry.h:534
bool has_nan(const vec3 &v)
Tests whether a 3d vector has a NaN (not a number) coordinate.
Definition: geometry.h:429
double triangle_area_2d(const double *p1, const double *p2, const double *p3)
Computes the area of a 2d triangle.
Definition: geometry.h:406
double angle(const vec3 &a, const vec3 &b)
Computes the angle between two 3d vectors.
Definition: geometry.h:266
double triangle_area_3d(const double *p1, const double *p2, const double *p3)
Computes the area of a 3d triangle.
Definition: geometry.h:326
double tetra_signed_volume(const vec3 &p1, const vec3 &p2, const vec3 &p3, const vec3 &p4)
Computes the signed volume of a 3d tetrahedron.
Definition: geometry.h:463
vec3 barycenter(const vec3 &p1, const vec3 &p2)
Computes the barycenter of two points in 3d.
Definition: geometry.h:189
vec2 triangle_circumcenter(const vec2 &p1, const vec2 &p2, const vec2 &p3)
Computes the center of the circumscribed circle of a 2d triangle.
float64 random_float64()
Returns a 64 bits float between 0 and 1.
bool is_nan(float32 x)
Checks whether a 32 bits float is "not a number".
Global Vorpaline namespace.
Matrix< 4, Numeric::float64 > mat4
Represents a 4x4 matrix.
Definition: geometry.h:133
bool bboxes_overlap(const Box &B1, const Box &B2)
Tests whether two Boxes have a non-empty intersection.
Definition: geometry.h:701
vecng< 3, Numeric::float32 > vec3f
Represents points and vectors in 3d with single-precision coordinates.
Definition: geometry.h:85
vecng< 4, Numeric::float32 > vec4f
Represents points and vectors in 4d with single-precision coordinates.
Definition: geometry.h:92
void bbox_union(Box &target, const Box &B1, const Box &B2)
Computes the smallest Box that encloses two Boxes.
Definition: geometry.h:720
vecng< 3, Numeric::float64 > vec3
Represents points and vectors in 3d.
Definition: geometry.h:65
vecng< 3, Numeric::int32 > vec3i
Represents points and vectors in 3d with integer coordinates.
Definition: geometry.h:107
T det3x3(const T &a11, const T &a12, const T &a13, const T &a21, const T &a22, const T &a23, const T &a31, const T &a32, const T &a33)
Computes a three-by-three determinant.
Definition: determinant.h:69
T det4x4(const T &a11, const T &a12, const T &a13, const T &a14, const T &a21, const T &a22, const T &a23, const T &a24, const T &a31, const T &a32, const T &a33, const T &a34, const T &a41, const T &a42, const T &a43, const T &a44)
Computes a four-by-four determinant.
Definition: determinant.h:85
void geo_clamp(T &x, T min, T max)
Clamps a value to a range.
Definition: numeric.h:314
mat4 create_scaling_matrix(double s)
Creates a scaling matrix.
Definition: geometry.h:957
vecng< 3, FT > transform_vector(const vecng< 3, FT > &v, const Matrix< 4, FT > &m)
Applies a 3d transform to a 3d vector.
Definition: geometry.h:804
geo_index_t index_t
The type for storing and manipulating indices.
Definition: numeric.h:329
double det(const mat2 &M)
Computes the determinant of a 2x2 matrix.
Definition: geometry.h:142
vecng< 4, Numeric::float64 > vec4
Represents points and vectors in 4d.
Definition: geometry.h:71
mat4 create_translation_matrix(const vec3 &T)
Creates a translation matrix from a vector.
Definition: geometry.h:940
vecng< 2, Numeric::int32 > vec2i
Represents points and vectors in 2d with integer coordinates.
Definition: geometry.h:100
T det2x2(const T &a11, const T &a12, const T &a21, const T &a22)
Computes a two-by-two determinant.
Definition: determinant.h:58
Matrix< 3, Numeric::float64 > mat3
Represents a 3x3 matrix.
Definition: geometry.h:127
vecng< 2, Numeric::float32 > vec2f
Represents points and vectors in 2d with single-precision coordinates.
Definition: geometry.h:78
vecng< 2, Numeric::float64 > vec2
Represents points and vectors in 2d.
Definition: geometry.h:59
geo_coord_index_t coord_index_t
The type for storing coordinate indices, and iterating on the coordinates of a point.
Definition: numeric.h:363
vecng< 4, Numeric::int32 > vec4i
Represents points and vectors in 4d with integer coordinates.
Definition: geometry.h:114
Matrix< 2, Numeric::float64 > mat2
Represents a 2x2 matrix.
Definition: geometry.h:121
vecng< 3, FT > transform_point(const vecng< 3, FT > &v, const Matrix< 4, FT > &m)
Applies a 3d transform to a 3d point.
Definition: geometry.h:840
A 3D Plane.
Definition: geometry.h:607
Plane(const vec3 &p1, const vec3 &p2, const vec3 &p3)
Constructs the plane passing through three points.
Definition: geometry.h:615
Plane(const vec3 &p, const vec3 &n)
Constructs a plane passign through a point and orthogonal to a vector.
Definition: geometry.h:629
Plane(double a_in, double b_in, double c_in, double d_in)
Constructs a plane from the coefficients of its equation.
Definition: geometry.h:639
Plane()
Constructs an uninitialized plane.
Definition: geometry.h:651
vec3 normal() const
Gets the normal vector of the plane.
Definition: geometry.h:657
A Ray, in parametric form.
Definition: geometry.h:971
Ray()
Ray constructor.
Definition: geometry.h:982
Ray(vec3 O, vec3 D)
Ray constructor.
Definition: geometry.h:977