CGeometry.h
Go to the documentation of this file.
1 //==============================================================================
2 /*
3  Software License Agreement (BSD License)
4  Copyright (c) 2003-2016, CHAI3D.
5  (www.chai3d.org)
6 
7  All rights reserved.
8 
9  Redistribution and use in source and binary forms, with or without
10  modification, are permitted provided that the following conditions
11  are met:
12 
13  * Redistributions of source code must retain the above copyright
14  notice, this list of conditions and the following disclaimer.
15 
16  * Redistributions in binary form must reproduce the above
17  copyright notice, this list of conditions and the following
18  disclaimer in the documentation and/or other materials provided
19  with the distribution.
20 
21  * Neither the name of CHAI3D nor the names of its contributors may
22  be used to endorse or promote products derived from this software
23  without specific prior written permission.
24 
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  POSSIBILITY OF SUCH DAMAGE.
37 
38  \author <http://www.chai3d.org>
39  \author Francois Conti
40  \version 3.2.0 $Rev: 2171 $
41 */
42 //==============================================================================
43 
44 //------------------------------------------------------------------------------
45 #ifndef CGeometryH
46 #define CGeometryH
47 //------------------------------------------------------------------------------
48 #include "math/CPolySolver.h"
49 //------------------------------------------------------------------------------
50 
51 //------------------------------------------------------------------------------
52 namespace chai3d {
53 //------------------------------------------------------------------------------
54 
55 //==============================================================================
63 //==============================================================================
64 
65 //------------------------------------------------------------------------------
69 //------------------------------------------------------------------------------
70 
72 
73 //==============================================================================
88 //==============================================================================
89 inline double cTriangleArea(const cVector3d& a_vertex0,
90  const cVector3d& a_vertex1,
91  const cVector3d& a_vertex2)
92 {
93  cVector3d u, v;
94  a_vertex1.subr(a_vertex0, u);
95  a_vertex2.subr(a_vertex0, v);
96  return (0.5 * (cCross(u,v).length()));
97 }
98 
99 
100 //==============================================================================
116 //==============================================================================
118  const cVector3d& a_planePoint,
119  const cVector3d& a_planeNormal)
120 {
121  cVector3d n = a_planeNormal;
122 
123  // compute a projection matrix
124  cMatrix3d projectionMatrix;
125  projectionMatrix.set(
126  (n(1) * n(1)) + (n(2) * n(2)), -(n(0) * n(1) ),-(n(0) * n(2)),
127  -(n(1) * n(0)), (n(0) * n(0)) + (n(2) * n(2) ),-(n(1) * n(2)),
128  -(n(2) * n(0)),-(n(2) * n(1)), (n(0) * n(0) ) + (n(1) * n(1))
129  );
130 
131  // project point on plane and return projected point.
132  cVector3d point;
133  a_point.subr(a_planePoint, point);
134  projectionMatrix.mul(point);
135  point.add(a_planePoint);
136 
137  // return result
138  return (point);
139 }
140 
141 
142 //==============================================================================
158 //==============================================================================
160  const cVector3d& a_planePoint0,
161  const cVector3d& a_planePoint1,
162  const cVector3d& a_planePoint2)
163 {
164  // create two vectors from the three input points lying in the projection plane.
165  cVector3d v01, v02;
166  a_planePoint1.subr(a_planePoint0, v01);
167  a_planePoint2.subr(a_planePoint0, v02);
168 
169  // compute the normal vector of the plane
170  cVector3d n;
171  v01.crossr(v02, n);
172  n.normalize();
173 
174  // return projected point
175  return (cProjectPointOnPlane(a_point,a_planePoint0,n));
176 }
177 
178 
179 //==============================================================================
209 //==============================================================================
210 inline void cProjectPointOnPlane(const cVector3d& a_point,
211  const cVector3d& a_planePoint0,
212  const cVector3d& a_planePoint1,
213  const cVector3d& a_planePoint2,
214  double& a_r01,
215  double& a_r02)
216 {
217  cVector3d v01 = cSub(a_planePoint1, a_planePoint0);
218  cVector3d v02 = cSub(a_planePoint2, a_planePoint0);
219  cVector3d point = cSub(a_point, a_planePoint0);
220 
221  // matrix
222  double m00 = v01(0) * v01(0) + v01(1) * v01(1) + v01(2) * v01(2);
223  double m01 = v01(0) * v02(0) + v01(1) * v02(1) + v01(2) * v02(2);
224  double m10 = m01;
225  double m11 = v02(0) * v02(0) + v02(1) * v02(1) + v02(2) * v02(2);
226  double det = m00 * m11 - m10 * m01;
227 
228  // vector
229  double vm0 = v01(0) * point(0) + v01(1) * point(1) + v01(2) * point(2);
230  double vm1 = v02(0) * point(0) + v02(1) * point(1) + v02(2) * point(2);
231 
232  // inverse
233  a_r01 = (1.0 / det) * ( m11 * vm0 - m01 * vm1);
234  a_r02 = (1.0 / det) * (-m10 * vm0 + m00 * vm1);
235 }
236 
237 
238 //==============================================================================
254 //==============================================================================
256  const cVector3d& a_pointOnLine,
257  const cVector3d& a_directionOfLine)
258 {
259  // temp variable
260  cVector3d point, result;
261 
262  // compute norm of line direction
263  double lengthDirSq = a_directionOfLine.lengthsq();
264 
265  if (lengthDirSq > 0.0)
266  {
267  a_point.subr(a_pointOnLine, point);
268 
269  a_directionOfLine.mulr( (point.dot(a_directionOfLine) / (lengthDirSq)),
270  result);
271 
272  result.add(a_pointOnLine);
273  return (result);
274  }
275  else
276  {
277  return (a_pointOnLine);
278  }
279 }
280 
281 
282 //==============================================================================
298 //==============================================================================
300  const cVector3d& a_segmentPointA,
301  const cVector3d& a_segmentPointB)
302 {
303  // if both points are equal
304  if (a_segmentPointA.equals(a_segmentPointB))
305  {
306  return (a_segmentPointA);
307  }
308 
309  // compute line
310  cVector3d segmentAB;
311  a_segmentPointB.subr(a_segmentPointA, segmentAB);
312 
313  // project tool onto segment
314  cVector3d projection = cProjectPointOnLine(a_point, a_segmentPointA, segmentAB);
315 
316  double distanceAB = segmentAB.lengthsq();
317  double distanceAP = cDistanceSq(projection, a_segmentPointA);
318  double distanceBP = cDistanceSq(projection, a_segmentPointB);
319 
320  if (distanceAP > distanceAB)
321  {
322  return(a_segmentPointB);
323  }
324  else
325  if (distanceBP > distanceAB)
326  {
327  return(a_segmentPointA);
328  }
329  else
330  {
331  return(projection);
332  }
333 }
334 
335 
336 //==============================================================================
356 //==============================================================================
358  const double& a_height,
359  const double& a_radius)
360 {
361  cVector3d center(0.0, 0.0, a_height);
362  cVector3d pointProj(a_point);
363 
364  pointProj(2) = a_height;
365 
366  cVector3d ray = cSub (pointProj, center);
367 
368  if (ray.length() < a_radius) return (pointProj);
369  else
370  {
371  ray.normalize();
372  return center + a_radius * ray;
373  }
374 }
375 
376 
377 //==============================================================================
393 //==============================================================================
395  const cVector3d& a_vertex0,
396  const cVector3d& a_vertex1,
397  const cVector3d& a_vertex2)
398 {
399  cVector3d result;
400 
401  // project point on plane
402  double r01, r02;
403  cProjectPointOnPlane(a_point, a_vertex0, a_vertex1, a_vertex2, r01, r02);
404 
405  // check if point in located inside triangle
406  if ((r01 >= 0.0) && (r02 >= 0.0) && (r01 <= 1.0) && (r02 <= 1.0) && ((r01 + r02) <= 1.0))
407  {
408  result = a_vertex0 + r01 * (a_vertex1 - a_vertex0) + r02 * (a_vertex2 - a_vertex0);
409  }
410  else
411  {
412  // project point on edge 01
413  cVector3d p01 = cProjectPointOnSegment(a_point, a_vertex0, a_vertex1);
414 
415  // project point on edge 02
416  cVector3d p02 = cProjectPointOnSegment(a_point, a_vertex0, a_vertex2);
417 
418  // project point on edge 12
419  cVector3d p12 = cProjectPointOnSegment(a_point, a_vertex1, a_vertex2);
420 
421  // check for nearest point
422  double d01 = cDistanceSq(a_point, p01);
423  double d02 = cDistanceSq(a_point, p02);
424  double d12 = cDistanceSq(a_point, p12);
425 
426  if (d01 < d02)
427  {
428  if (d01 < d12)
429  {
430  result = p01;
431  }
432  else
433  {
434  result = p12;
435  }
436  }
437  else
438  {
439  if (d02 < d12)
440  {
441  result = p02;
442  }
443  else
444  {
445  result = p12;
446  }
447  }
448  }
449 
450  return (result);
451 }
452 
453 
454 //==============================================================================
469 //==============================================================================
470 inline cVector3d cProject(const cVector3d& a_vector0,
471  const cVector3d& a_vector1)
472 {
473  cVector3d result;
474 
475  // compute projection
476  double lengthSq = a_vector1.lengthsq();
477  a_vector1.mulr( (a_vector0.dot(a_vector1) / (lengthSq)), result);
478 
479  // return result
480  return (result);
481 }
482 
483 
484 //==============================================================================
500 //==============================================================================
501 inline double cDistanceToLine(const cVector3d& a_point,
502  const cVector3d& a_linePoint1,
503  const cVector3d& a_linePoint2)
504 {
505  cVector3d point = cProjectPointOnLine(a_point, a_linePoint1, cSub(a_linePoint2, a_linePoint1));
506  return (cDistance(a_point, point));
507 }
508 
509 
510 //==============================================================================
525 //==============================================================================
526 inline cVector3d cComputeSurfaceNormal(const cVector3d& a_surfacePoint0,
527  const cVector3d& a_surfacePoint1,
528  const cVector3d& a_surfacePoint2)
529 {
530  cVector3d v01, v02, result;
531 
532  // compute surface normal
533  a_surfacePoint1.subr(a_surfacePoint0, v01);
534  a_surfacePoint2.subr(a_surfacePoint0, v02);
535  v01.normalize();
536  v02.normalize();
537  v01.crossr(v02, result);
538  result.normalize();
539 
540  // return result
541  return (result);
542 }
543 
544 
545 //==============================================================================
563 //==============================================================================
564 inline bool cBoxContains(const cVector3d& a_point,
565  const cVector3d& a_boxMin,
566  const cVector3d& a_boxMax)
567 {
568  if ((a_point(0) >= a_boxMin(0) ) && (a_point(0) <= a_boxMax(0)) &&
569  (a_point(1) >= a_boxMin(1) ) && (a_point(1) <= a_boxMax(1)) &&
570  (a_point(2) >= a_boxMin(2) ) && (a_point(2) <= a_boxMax(2)))
571  {
572  return (true);
573  }
574  else
575  {
576  return (false);
577  }
578 }
579 
580 
581 //==============================================================================
610 //==============================================================================
611 inline int cIntersectionSegmentPlane(const cVector3d& a_segmentPointA,
612  const cVector3d& a_segmentPointB,
613  const cVector3d& a_planePos,
614  const cVector3d& a_planeNormal,
615  cVector3d& a_collisionPoint,
616  cVector3d& a_collisionNormal)
617 {
618  cVector3d d = a_segmentPointB - a_segmentPointA;
619  cVector3d p = a_segmentPointA;
620  double length = d.length();
621 
622  // sanity check
623  if (cZero(length))
624  {
625  return (0);
626  }
627 
628  // normalize d
629  d.mul(1.0 / length);
630 
631  // compute intersection between segment and disk plane
632  double c[2];
633  double s[1];
634 
635  c[0] = a_planeNormal(0)*p(0) - a_planeNormal(0)*a_planePos(0) +
636  a_planeNormal(1)*p(1) - a_planeNormal(1)*a_planePos(1) +
637  a_planeNormal(2)*p(2) - a_planeNormal(2)*a_planePos(2);
638  c[1] = a_planeNormal(0)*d(0) + a_planeNormal(1)*d(1) + a_planeNormal(2)*d(2);
639 
640  int num = cSolveLinear(c, s);
641 
642  if (num == 0)
643  {
644  return (0);
645  }
646  else
647  {
648  if ((s[0] >= 0.0) && (s[0] <= length))
649  {
650  a_collisionPoint = p + s[0] * d;
651  if (cDot(a_planeNormal, cSub(a_segmentPointA, a_collisionPoint)) >= 0.0)
652  {
653  a_collisionNormal = a_planeNormal;
654  }
655  else
656  {
657  a_collisionNormal =-a_planeNormal;
658  }
659  return (1);
660  }
661  else
662  {
663  return (0);
664  }
665  }
666 }
667 
668 
669 //==============================================================================
699 //==============================================================================
700 inline int cIntersectionSegmentDisk(const cVector3d& a_segmentPointA,
701  const cVector3d& a_segmentPointB,
702  const cVector3d& a_diskPos,
703  const cVector3d& a_diskNormal,
704  const double& a_diskRadius,
705  cVector3d& a_collisionPoint,
706  cVector3d& a_collisionNormal)
707 {
708  // compute intersection between segment and disk plane
709  if (cIntersectionSegmentPlane(a_segmentPointA,
710  a_segmentPointB,
711  a_diskPos,
712  a_diskNormal,
713  a_collisionPoint,
714  a_collisionNormal) == 0)
715  {
716  return (0);
717  }
718 
719  // check if intersection point within disk
720  if (cDistance(a_collisionPoint, a_diskPos) <= a_diskRadius)
721  {
722  return (1);
723  }
724  else
725  {
726  return (0);
727  }
728 }
729 
730 
731 //==============================================================================
767 //==============================================================================
768 inline int cIntersectionSegmentSphere(const cVector3d& a_segmentPointA,
769  const cVector3d& a_segmentPointB,
770  const cVector3d& a_spherePos,
771  const double& a_sphereRadius,
772  cVector3d& a_collisionPoint0,
773  cVector3d& a_collisionNormal0,
774  cVector3d& a_collisionPoint1,
775  cVector3d& a_collisionNormal1)
776 {
777  // temp variables
778  cVector3d AB, CA;
779  a_segmentPointB.subr(a_segmentPointA, AB);
780  a_segmentPointA.subr(a_spherePos, CA);
781  double radiusSq = a_sphereRadius * a_sphereRadius;
782 
783  double a = AB.lengthsq();
784  double b = 2.0 * cDot(AB, CA);
785  double c = CA.lengthsq() - radiusSq;
786 
787  // invalid segment
788  if (a == 0)
789  {
790  return (0);
791  }
792 
793  double d = b*b - 4*a*c;
794 
795  // segment ray is located outside of sphere
796  if (d < 0)
797  {
798  return (0);
799  }
800 
801  // segment ray intersects sphere
802  d = sqrt(d);
803  double e = 2.0 * a;
804 
805  // compute both solutions
806  double u0 = (-b + d) / e;
807  double u1 = (-b - d) / e;
808 
809  // check if the solutions are located along the segment AB
810  bool valid_u0 = cContains(u0, 0.0, 1.0);
811  bool valid_u1 = cContains(u1, 0.0, 1.0);
812 
813  // two intersection points are located along segment AB
814  if (valid_u0 && valid_u1)
815  {
816  if (u0 > u1) { cSwap(u0, u1); }
817 
818  // compute point 0
819  AB.mulr(u0, a_collisionPoint0);
820  a_collisionPoint0.add(a_segmentPointA);
821 
822  a_collisionPoint0.subr(a_spherePos, a_collisionNormal0);
823  a_collisionNormal0.normalize();
824 
825  // compute point 1
826  AB.mulr(u1, a_collisionPoint1);
827  a_collisionPoint1.add(a_segmentPointA);
828 
829  a_collisionPoint1.subr(a_spherePos, a_collisionNormal1);
830  a_collisionNormal1.normalize();
831 
832  return (2);
833  }
834 
835  // one intersection point is located along segment AB
836  else if (valid_u0)
837  {
838  // compute point 0
839  AB.mulr(u0, a_collisionPoint0);
840  a_collisionPoint0.add(a_segmentPointA);
841 
842  a_collisionPoint0.subr(a_spherePos, a_collisionNormal0);
843  a_collisionNormal0.normalize();
844 
845  // check dot product to see if the intial segment point is located
846  // inside the sphere.
847  double dotProduct = cDot(AB, a_collisionNormal0);
848  if (dotProduct < 0.0)
849  {
850  return (1);
851  }
852  else
853  {
854  return (0);
855  }
856  }
857 
858  // one intersection point is located along segment AB
859  else if (valid_u1)
860  {
861  // compute point 0
862  AB.mulr(u1, a_collisionPoint0);
863  a_collisionPoint0.add(a_segmentPointA);
864 
865  a_collisionPoint0.subr(a_spherePos, a_collisionNormal0);
866  a_collisionNormal0.normalize();
867 
868  // check dot product to see if the intial segment point is located
869  // inside the sphere.
870  double dotProduct = cDot(AB, a_collisionNormal0);
871  if (dotProduct < 0.0)
872  {
873  return (1);
874  }
875  else
876  {
877  return (0);
878  }
879  }
880 
881  // both points are located outside of the segment AB
882  else
883  {
884  return (0);
885  }
886 }
887 
888 
889 //==============================================================================
927 //==============================================================================
928 inline int cIntersectionSegmentEllipsoid(const cVector3d& a_segmentPointA,
929  const cVector3d& a_segmentPointB,
930  const cVector3d& a_pos,
931  const double& a_radiusX,
932  const double& a_radiusY,
933  const double& a_radiusZ,
934  cVector3d& a_collisionPoint0,
935  cVector3d& a_collisionNormal0,
936  cVector3d& a_collisionPoint1,
937  cVector3d& a_collisionNormal1)
938 {
939  // scale to sphere
940  double radius = cMin(a_radiusX, cMin(a_radiusY, a_radiusZ));
941  double scaleX = a_radiusX / radius;
942  double scaleY = a_radiusY / radius;
943  double scaleZ = a_radiusZ / radius;
944 
945  cVector3d segmentPointA = a_segmentPointA;
946  segmentPointA.mul(1.0 / scaleX, 1.0 / scaleY, 1.0 / scaleZ);
947  cVector3d segmentPointB = a_segmentPointB;
948  segmentPointB.mul(1.0 / scaleX, 1.0 / scaleY, 1.0 / scaleZ);
949 
950  // temp variables
951  cVector3d AB, CA;
952  segmentPointB.subr(segmentPointA, AB);
953  segmentPointA.subr(a_pos, CA);
954  double radiusSq = radius * radius;
955 
956  double a = AB.lengthsq();
957  double b = 2.0 * cDot(AB, CA);
958  double c = CA.lengthsq() - radiusSq;
959 
960  // invalid segment
961  if (a == 0)
962  {
963  return (0);
964  }
965 
966  double d = b*b - 4 * a*c;
967 
968  // segment ray is located outside of sphere
969  if (d < 0)
970  {
971  return (0);
972  }
973 
974  // segment ray intersects sphere
975  d = sqrt(d);
976  double e = 2.0 * a;
977 
978  // compute both solutions
979  double u0 = (-b + d) / e;
980  double u1 = (-b - d) / e;
981 
982  // check if the solutions are located along the segment AB
983  bool valid_u0 = cContains(u0, 0.0, 1.0);
984  bool valid_u1 = cContains(u1, 0.0, 1.0);
985 
986  // two intersection points are located along segment AB
987  if (valid_u0 && valid_u1)
988  {
989  if (u0 > u1) { cSwap(u0, u1); }
990 
991  // compute point 0
992  AB.mulr(u0, a_collisionPoint0);
993  a_collisionPoint0.add(segmentPointA);
994  a_collisionPoint0.subr(a_pos, a_collisionNormal0);
995  a_collisionNormal0.normalize();
996  a_collisionNormal0.mul(1.0 / scaleX, 1.0 / scaleY, 1.0 / scaleZ);
997  a_collisionPoint0.mul(scaleX, scaleY, scaleZ);
998 
999  // compute point 1
1000  AB.mulr(u1, a_collisionPoint1);
1001  a_collisionPoint1.add(segmentPointA);
1002  a_collisionPoint1.subr(a_pos, a_collisionNormal1);
1003  a_collisionNormal1.normalize();
1004  a_collisionNormal1.mul(1.0 / scaleX, 1.0 / scaleY, 1.0 / scaleZ);
1005  a_collisionPoint1.mul(scaleX, scaleY, scaleZ);
1006 
1007  return (2);
1008  }
1009 
1010  // one intersection point is located along segment AB
1011  else if (valid_u0)
1012  {
1013  // compute point 0
1014  AB.mulr(u0, a_collisionPoint0);
1015  a_collisionPoint0.add(segmentPointA);
1016  a_collisionPoint0.subr(a_pos, a_collisionNormal0);
1017  a_collisionNormal0.normalize();
1018  a_collisionNormal0.mul(1.0 / scaleX, 1.0 / scaleY, 1.0 / scaleZ);
1019  a_collisionPoint0.mul(scaleX, scaleY, scaleZ);
1020 
1021  // check dot product to see if the intial segment point is located
1022  // inside the sphere.
1023  double dotProduct = cDot(AB, a_collisionNormal0);
1024  if (dotProduct < 0.0)
1025  {
1026  return (1);
1027  }
1028  else
1029  {
1030  return (0);
1031  }
1032  }
1033 
1034  // one intersection point is located along segment AB
1035  else if (valid_u1)
1036  {
1037  // compute point 0
1038  AB.mulr(u1, a_collisionPoint0);
1039  a_collisionPoint0.add(segmentPointA);
1040  a_collisionPoint0.subr(a_pos, a_collisionNormal0);
1041  a_collisionNormal0.normalize();
1042  a_collisionNormal0.mul(1.0 / scaleX, 1.0 / scaleY, 1.0 / scaleZ);
1043  a_collisionPoint0.mul(scaleX, scaleY, scaleZ);
1044 
1045  // check dot product to see if the intial segment point is located
1046  // inside the sphere.
1047  double dotProduct = cDot(AB, a_collisionNormal0);
1048  if (dotProduct < 0.0)
1049  {
1050  return (1);
1051  }
1052  else
1053  {
1054  return (0);
1055  }
1056  }
1057 
1058  // both points are located outside of the segment AB
1059  else
1060  {
1061  return (0);
1062  }
1063 }
1064 
1065 
1066 //==============================================================================
1106 //==============================================================================
1107 inline int cIntersectionSegmentToplessCylinder(const cVector3d& a_segmentPointA,
1108  const cVector3d& a_segmentPointB,
1109  const cVector3d& a_cylinderPointA,
1110  const cVector3d& a_cylinderPointB,
1111  const double& a_cylinderRadius,
1112  cVector3d& a_collisionPoint0,
1113  cVector3d& a_collisionNormal0,
1114  double& a_collisionPointRelPosAB0,
1115  cVector3d& a_collisionPoint1,
1116  cVector3d& a_collisionNormal1,
1117  double& a_collisionPointRelPosAB1)
1118 {
1119  // compute some initial values
1120  cVector3d cylinderAB = a_cylinderPointB - a_cylinderPointA;
1121  double lengthCylinderAB = cylinderAB.length();
1122 
1123  // sanity check
1124  if (lengthCylinderAB == 0.0) { return (0); }
1125 
1126  // compute more initial values
1127  cVector3d cylinderDir = cNormalize(cylinderAB);
1128  cVector3d RC = a_segmentPointA - a_cylinderPointA;
1129  cVector3d segmentAB = a_segmentPointB - a_segmentPointA;
1130  if (segmentAB.lengthsq() == 0) { return (0); }
1131 
1132  cVector3d segmentDir = cNormalize(segmentAB);
1133  cVector3d n = cCross(segmentDir, cylinderDir);
1134 
1135  // segment is parallel to cylinder
1136  double length = n.length();
1137  if (length == 0.0)
1138  {
1139  return (0);
1140  }
1141 
1142  n.normalize();
1143  double d = fabs (cDot (RC,n));
1144 
1145  if (d <= a_cylinderRadius)
1146  {
1147  cVector3d O = cCross(RC, cylinderDir);
1148  double t = -cDot(O,n) / length;
1149  O = cCross(n, cylinderDir);
1150  O.normalize();
1151  double s = fabs(sqrt(a_cylinderRadius*a_cylinderRadius - d*d) / cDot(segmentDir,O));
1152  double u0 = t - s;
1153  double u1 = t + s;
1154 
1155  // reorder solutions
1156  if (u0 > u1) { cSwap (u0,u1); }
1157 
1158  bool valid_u0 = true;
1159  bool valid_u1 = true;
1160 
1161  // check if solutions along segment
1162  double lengthAB = segmentAB.length();
1163  if (!cContains(u0, 0.0, lengthAB)) { valid_u0 = false; }
1164  if (!cContains(u1, 0.0, lengthAB)) { valid_u1 = false; }
1165 
1166  // check if solutions lay along cylinder
1167  cVector3d P0, P1;
1168  cVector3d cylinderDirNeg = cNegate(cylinderDir);
1169 
1170  if (valid_u0)
1171  {
1172  P0 = a_segmentPointA + u0 * segmentDir;
1173  cVector3d P0A = cSub(P0, a_cylinderPointA);
1174  cVector3d P0B = cSub(P0, a_cylinderPointB);
1175 
1176  double cosAngleA = cCosAngle(cylinderDir, P0A);
1177  double cosAngleB = cCosAngle(cylinderDirNeg, P0B);
1178 
1179  if ((cosAngleA <= 0.0) || (cosAngleB <= 0.0))
1180  {
1181  valid_u0 = false;
1182  }
1183  else
1184  {
1185  a_collisionPointRelPosAB0 = cosAngleA * (P0A.length() / lengthCylinderAB);
1186  }
1187  }
1188 
1189  if (valid_u1)
1190  {
1191  P1 = a_segmentPointA + u1 * segmentDir;
1192  cVector3d P1A = cSub(P1, a_cylinderPointA);
1193  cVector3d P1B = cSub(P1, a_cylinderPointB);
1194 
1195  double cosAngleA = cCosAngle(cylinderDir, P1A);
1196  double cosAngleB = cCosAngle(cylinderDirNeg, P1B);
1197 
1198  if ((cosAngleA <= 0.0) || (cosAngleB <= 0.0))
1199  {
1200  valid_u1 = false;
1201  }
1202  else
1203  {
1204  a_collisionPointRelPosAB1 = cosAngleA * (P1A.length() / lengthCylinderAB);
1205  }
1206  }
1207 
1208  if (valid_u0 && valid_u1)
1209  {
1210  a_collisionPoint0 = P0;
1211  a_collisionNormal0 = cNormalize(cCross(cylinderDir, cCross(cSub(P0, a_cylinderPointA), cylinderDir)));
1212  a_collisionPoint1 = P1;
1213  a_collisionNormal1 = cNormalize(cCross(cylinderDir, cCross(cSub(P1, a_cylinderPointA), cylinderDir)));
1214  return (2);
1215  }
1216  else if (valid_u0)
1217  {
1218  a_collisionPoint0 = P0;
1219  a_collisionNormal0 = cNormalize(cCross(cylinderDir, cCross(cSub(P0, a_cylinderPointA), cylinderDir)));
1220 
1221  // check dot product to see if the intial segment point is located inside the cylinder.
1222  double dotProduct = cDot(segmentAB, a_collisionNormal0);
1223  if (dotProduct < 0.0)
1224  {
1225  return (1);
1226  }
1227  else
1228  {
1229  return (0);
1230  }
1231  }
1232  else if (valid_u1)
1233  {
1234  a_collisionPoint0 = P1;
1235  a_collisionNormal0 = cNormalize(cCross(cylinderDir, cCross(cSub(P1, a_cylinderPointA), cylinderDir)));
1236 
1237  // check dot product to see if the intial segment point is located inside the cylinder.
1238  double dotProduct = cDot(segmentAB, a_collisionNormal0);
1239  if (dotProduct < 0.0)
1240  {
1241  return (1);
1242  }
1243  else
1244  {
1245  return (0);
1246  }
1247  }
1248  }
1249 
1250  return (0);
1251 }
1252 
1253 
1254 //==============================================================================
1287 //==============================================================================
1288 inline int cIntersectionSegmentCylinder(const cVector3d& a_segmentPointA,
1289  const cVector3d& a_segmentPointB,
1290  const double& a_baseRadius,
1291  const double& a_topRadius,
1292  const double& a_height,
1293  cVector3d& a_collisionPoint,
1294  cVector3d& a_collisionNormal)
1295 {
1296  // initialization
1297  cVector3d p = a_segmentPointA;
1298  cVector3d d = a_segmentPointB - a_segmentPointA;
1299  double length = d.length();
1300 
1301  // sanity check
1302  if (cZero(length))
1303  {
1304  return (0);
1305  }
1306  d.mul(1.0 / length);
1307 
1308  // compute collision with cylinder side
1309  double A = a_baseRadius;
1310  double B = (a_topRadius - a_baseRadius) / a_height;
1311 
1312  double c[3];
1313  double s[2];
1314 
1315  c[0] =-2.0*A*B*p(2) - cSqr(B*p(2)) - cSqr(A) + cSqr(p(0)) + cSqr(p(1));
1316  c[1] = 2.0*p(0)*d(0) + 2.0*p(1)*d(1) - 2.0*A*B*d(2) - 2.0*cSqr(B)*p(2)*d(2);
1317  c[2] = cSqr(d(0)) + cSqr(d(1)) - cSqr(B*d(2));
1318 
1319  int numCol = cSolveQuadric(c, s);
1320 
1321  // compute collision with top cap
1322  cVector3d collisionPointTop, collisionNormalTop;
1323 
1324  int numColTop = cIntersectionSegmentDisk(a_segmentPointA,
1325  a_segmentPointB,
1326  cVector3d(0.0, 0.0, a_height),
1327  cVector3d(0.0, 0.0, 1.0),
1328  a_topRadius,
1329  collisionPointTop,
1330  collisionNormalTop);
1331 
1332  // compute collision with base cap
1333  cVector3d collisionPointBase, collisionNormalBase;
1334 
1335  int numColBase = cIntersectionSegmentDisk(a_segmentPointA,
1336  a_segmentPointB,
1337  cVector3d(0.0, 0.0, 0.0),
1338  cVector3d(0.0, 0.0,-1.0),
1339  a_baseRadius,
1340  collisionPointBase,
1341  collisionNormalBase);
1342 
1343  // evaluate solutions
1344  bool hit = false;
1345  double distance = C_LARGE;
1346 
1347  // check top cap
1348  if (numColTop > 0)
1349  {
1350  hit = true;
1351  distance = cDistance(a_segmentPointA, collisionPointTop);
1352  a_collisionPoint = collisionPointTop;
1353  a_collisionNormal = cVector3d(0.0, 0.0, 1.0);
1354  }
1355 
1356  // check base cap
1357  if (numColBase > 0)
1358  {
1359  hit = true;
1360  double dist = cDistance(a_segmentPointA, collisionPointBase);
1361  if (dist < distance)
1362  {
1363  a_collisionPoint = collisionPointBase;
1364  a_collisionNormal = cVector3d(0.0, 0.0,-1.0);
1365  distance = dist;
1366  }
1367  }
1368 
1369  // check cylinder solution 1
1370  if (numCol > 0)
1371  {
1372  if ((s[0] >= 0.0) && (s[0] <= length) && (s[0] < distance))
1373  {
1374  cVector3d collisionPoint = p + d * s[0];
1375  if ((collisionPoint(2) > 0.0) && (collisionPoint(2) < a_height))
1376  {
1377  cVector3d normal(collisionPoint(0), collisionPoint(1), 0.0);
1378  normal.normalize();
1379  normal(2) = (a_baseRadius - a_topRadius) / a_height;
1380  a_collisionNormal = normal;
1381  a_collisionPoint = collisionPoint;
1382  distance = s[0];
1383  hit = true;
1384  }
1385  }
1386  }
1387 
1388  // check cylinder solution 2
1389  if (numCol > 1)
1390  {
1391  if ((s[1] >= 0.0) && (s[1] <= length) && (s[1] < distance))
1392  {
1393  cVector3d collisionPoint = p + d * s[1];
1394  if ((collisionPoint(2) > 0.0) && (collisionPoint(2) < a_height))
1395  {
1396  cVector3d normal(collisionPoint(0), collisionPoint(1), 0.0);
1397  normal.normalize();
1398  normal(2) = (a_baseRadius - a_topRadius) / a_height;
1399  a_collisionNormal = normal;
1400  a_collisionPoint = collisionPoint;
1401  hit = true;
1402  }
1403  }
1404  }
1405 
1406  if (hit)
1407  {
1408  return (1);
1409  }
1410  else
1411  {
1412  return (0);
1413  }
1414 }
1415 
1416 
1417 //==============================================================================
1447 //==============================================================================
1448 inline int cIntersectionSegmentBox(const cVector3d& a_segmentPointA,
1449  const cVector3d& a_segmentPointB,
1450  const cVector3d& a_boxMin,
1451  const cVector3d& a_boxMax,
1452  cVector3d& a_collisionPoint,
1453  cVector3d& a_collisionNormal)
1454 {
1455  double tmin = 0.0;
1456  double tmax = C_LARGE;
1457 
1458  cVector3d d = a_segmentPointB - a_segmentPointA;
1459  double distance = d.length();
1460  if (distance == 0)
1461  {
1462  return(0);
1463  }
1464  d.normalize();
1465 
1466  // for all three slabs
1467  double normalDir = 1.0;
1468  int normalAxis = 0;
1469 
1470  for (int i = 0; i<3; i++)
1471  {
1472  if (fabs(d(i)) < C_SMALL)
1473  {
1474  // ray is parallel to slab. No hit if origin not within slab
1475  if (a_segmentPointA(i) < a_boxMin(i) || a_segmentPointA(i) > a_boxMax(i))
1476  {
1477  return (0);
1478  }
1479  }
1480  else
1481  {
1482  // compute intersection t value of ray with near and far plane of slab
1483  double ood = 1.0 / d(i);
1484  double t1 = (a_boxMin(i) - a_segmentPointA(i)) * ood;
1485  double t2 = (a_boxMax(i) - a_segmentPointA(i)) * ood;
1486  int n = 1;
1487 
1488  // make t1 be intersection with near plane, t2 with far plane
1489  if (t1 > t2)
1490  {
1491  cSwap(t1, t2);
1492  n = -1;
1493  }
1494 
1495  // compute the intersection of slab intersection intervals
1496  if (t1 > tmin)
1497  {
1498  tmin = t1;
1499  normalAxis = i;
1500  normalDir = -n;
1501  }
1502 
1503  if (t2 < tmax)
1504  {
1505  tmax = t2;
1506  }
1507 
1508  // exit with no collision as soon as slab intersection becomes empty
1509  if (tmin > tmax)
1510  {
1511  return (0);
1512  }
1513  }
1514  }
1515 
1516  if (tmin > distance)
1517  {
1518  return (0);
1519  }
1520 
1521  // compute collision point and surface normal
1522  a_collisionPoint = a_segmentPointA + cMul(tmin, d);
1523  a_collisionNormal.zero();
1524  a_collisionNormal(normalAxis) = normalDir;
1525 
1526  return (1);
1527 }
1528 
1529 
1530 //==============================================================================
1560 //==============================================================================
1561 inline int cIntersectionSegmentTorus(const cVector3d& a_segmentPointA,
1562  const cVector3d& a_segmentPointB,
1563  const double& a_innerRadius,
1564  const double& a_outerRadius,
1565  cVector3d& a_collisionPoint,
1566  cVector3d& a_collisionNormal)
1567 {
1568  cVector3d collisionPoint, collisionNormal;
1569 
1570  // compute boundary box
1571  double width = a_outerRadius + a_innerRadius;
1572  cVector3d boxMin(-width,-width,-a_innerRadius);
1573  cVector3d boxMax( width, width, a_innerRadius);
1574 
1575  // check collision with boundary box
1576  if (cIntersectionSegmentBox(a_segmentPointA,
1577  a_segmentPointB,
1578  boxMin,
1579  boxMax,
1580  collisionPoint,
1581  collisionNormal) == 0)
1582  {
1583  return (0);
1584  }
1585 
1586  cVector3d p = a_segmentPointA;
1587  cVector3d d = cNormalize(a_segmentPointB - a_segmentPointA);
1588 
1589  double dd = cDot(d, d);
1590  double pd = cDot(p, d);
1591  double pp = cDot(p, p);
1592  double r2 = cSqr(a_innerRadius);
1593  double R2 = cSqr(a_outerRadius);
1594 
1595  double c[5];
1596  double s[4];
1597 
1598  c[4] = cSqr(dd);
1599  c[3] = 4.0 * dd * pd;
1600  c[2] = 4.0 * cSqr(pd) + 2.0 * dd * (pp - r2 - R2) + 4.0 * R2 * cSqr(d(2));
1601  c[1] = 4.0 * pd * (pp - r2 - R2) + 8.0 * R2 * p(2) * d(2);
1602  c[0] = cSqr(pp - r2 - R2) + 4.0 * R2 * cSqr(p(2)) - 4.0 * R2 * r2;
1603 
1604  int num = cSolveQuartic(c, s);
1605 
1606  if (num == 0)
1607  {
1608  // no solutions found
1609  return (0);
1610  }
1611 
1612  // search for nearest solution (sollision point)
1613  double sol = C_LARGE;
1614  for (int i=0; i<num; i++)
1615  {
1616  if (s[i] < sol)
1617  {
1618  sol = s[i];
1619  }
1620  }
1621 
1622  // compute point
1623  a_collisionPoint = p + sol * d;
1624 
1625  // compute surface normal
1626  cVector3d pt = cMul(a_outerRadius, cNormalize(cVector3d(a_collisionPoint(0), a_collisionPoint(1), 0.0)));
1627  a_collisionNormal = cNormalize(a_collisionPoint - pt);
1628 
1629  // return one collision point detected
1630  return (1);
1631 }
1632 
1633 
1634 //==============================================================================
1667 //==============================================================================
1668 inline bool cIntersectionSegmentTriangle(const cVector3d& a_segmentPointA,
1669  const cVector3d& a_segmentPointB,
1670  const cVector3d& a_triangleVertex0,
1671  const cVector3d& a_triangleVertex1,
1672  const cVector3d& a_triangleVertex2,
1673  const bool a_reportFrontSideCollision,
1674  const bool a_reportBackSideCollision,
1675  cVector3d& a_collisionPoint,
1676  cVector3d& a_collisionNormal,
1677  double& a_collisionPosVertex01,
1678  double& a_collisionPosVertex02
1679  )
1680 {
1681  // This value controls how close rays can be to parallel to the triangle
1682  // surface before we discard them
1683  const double C_INTERSECT_EPSILON = 10e-14f;
1684 
1685  // compute a ray and check its length
1686  cVector3d rayDir;
1687  a_segmentPointB.subr(a_segmentPointA, rayDir);
1688  double segmentLengthSquare = rayDir.lengthsq();
1689  if (segmentLengthSquare == 0.0) { return (false); }
1690 
1691  // Compute the triangle's normal
1692  cVector3d t_E0, t_E1, t_N;
1693  a_triangleVertex1.subr(a_triangleVertex0, t_E0);
1694  a_triangleVertex2.subr(a_triangleVertex0, t_E1);
1695  t_E0.crossr(t_E1, t_N);
1696 
1697  // If the ray is parallel to the triangle (perpendicular to the
1698  // normal), there's no collision
1699  double dotProduct = t_N.dot(rayDir);
1700  if (fabs(dotProduct)<10E-15f) return (false);
1701 
1702  if ((dotProduct < 0.0) && (a_reportFrontSideCollision == false)) return (false);
1703  if ((dotProduct > 0.0) && (a_reportBackSideCollision == false)) return (false);
1704 
1705  double t_T = cDot(t_N, cSub(a_triangleVertex0, a_segmentPointA)) / cDot(t_N, rayDir);
1706 
1707  if (t_T + C_INTERSECT_EPSILON < 0) return (false);
1708 
1709  cVector3d t_Q = cSub(cAdd(a_segmentPointA, cMul(t_T, rayDir)), a_triangleVertex0);
1710  double t_Q0 = cDot(t_E0,t_Q);
1711  double t_Q1 = cDot(t_E1,t_Q);
1712  double t_E00 = cDot(t_E0,t_E0);
1713  double t_E01 = cDot(t_E0,t_E1);
1714  double t_E11 = cDot(t_E1,t_E1);
1715  double t_D = (t_E00 * t_E11) - (t_E01 * t_E01);
1716 
1717  if ((t_D > -C_INTERSECT_EPSILON) && (t_D < C_INTERSECT_EPSILON)) return(false);
1718 
1719  double t_S0 = ((t_E11 * t_Q0) - (t_E01 * t_Q1)) / t_D;
1720  double t_S1 = ((t_E00 * t_Q1) - (t_E01 * t_Q0)) / t_D;
1721 
1722  // Collision has occurred. It is reported.
1723  if (
1724  (t_S0 >= 0.0 - C_INTERSECT_EPSILON) &&
1725  (t_S1 >= 0.0 - C_INTERSECT_EPSILON) &&
1726  ((t_S0 + t_S1) <= 1.0 + C_INTERSECT_EPSILON)
1727  )
1728  {
1729  cVector3d t_I = cAdd(a_triangleVertex0, cMul(t_S0,t_E0), cMul(t_S1, t_E1));
1730 
1731  // Square distance between ray origin and collision point.
1732  double distanceSquare = a_segmentPointA.distancesq(t_I);
1733 
1734  // check if collision occurred within segment. If yes, report collision
1735  if (distanceSquare <= segmentLengthSquare)
1736  {
1737  a_collisionPoint = cAdd(a_segmentPointA, cMul(t_T, rayDir));
1738  t_N.normalizer(a_collisionNormal);
1739  if (cCosAngle(a_collisionNormal, rayDir) > 0.0)
1740  {
1741  a_collisionNormal.negate();
1742  }
1743 
1744  a_collisionPosVertex01 = t_S0;
1745  a_collisionPosVertex02 = t_S1;
1746 
1747  return (true);
1748  }
1749  }
1750 
1751  // no collision occurred
1752  return (false);
1753 }
1754 
1756 
1757 //------------------------------------------------------------------------------
1758 } // namespace chai3d
1759 //------------------------------------------------------------------------------
1760 
1761 //------------------------------------------------------------------------------
1762 #endif // CGeometryH
1763 //------------------------------------------------------------------------------
1764 
1765 
This class implements a 3D vector.
Definition: CVector3d.h:88
cVector3d cProjectPointOnLine(const cVector3d &a_point, const cVector3d &a_pointOnLine, const cVector3d &a_directionOfLine)
This function computes the projection of a point onto a line.
Definition: CGeometry.h:255
const double C_SMALL
Small value near zero.
Definition: CConstants.h:103
cVector3d cProject(const cVector3d &a_vector0, const cVector3d &a_vector1)
This function computes the projection of a vector V0 onto a vector V1.
Definition: CGeometry.h:470
double cDistance(const cVector3d &a_point1, const cVector3d &a_point2)
This function computes the Euclidean distance between two points.
Definition: CMaths.h:953
void normalize()
This method normalizes this vector to length 1.
Definition: CVector3d.h:1054
void zero()
This method clears all vector components with zeros.
Definition: CVector3d.h:256
bool equals(const cVector3d &a_vector, const double a_epsilon=0.0) const
This method performs an equality test between two vectors.
Definition: CVector3d.h:1201
cVector3d cComputeSurfaceNormal(const cVector3d &a_surfacePoint0, const cVector3d &a_surfacePoint1, const cVector3d &a_surfacePoint2)
This function computes the surface normal of a plane.
Definition: CGeometry.h:526
int cIntersectionSegmentPlane(const cVector3d &a_segmentPointA, const cVector3d &a_segmentPointB, const cVector3d &a_planePos, const cVector3d &a_planeNormal, cVector3d &a_collisionPoint, cVector3d &a_collisionNormal)
This function computes the intersection between a segment and a plane.
Definition: CGeometry.h:611
double distancesq(const cVector3d &a_vector) const
This method computes the squared value distance between two points.
Definition: CVector3d.h:1172
int cSolveQuartic(double a_coefficient[5], double a_solution[4])
This function computes the solution of a quartic equation.
Definition: CPolySolver.h:272
void crossr(const cVector3d &a_vector, cVector3d &a_result) const
This method computes the cross product.
Definition: CVector3d.h:975
double cCosAngle(const cVector3d &a_vector1, const cVector3d &a_vector2)
This function computes the cosine of the angle between two vectors.
Definition: CMaths.h:1424
cVector3d cAdd(const cVector3d &a_vector1, const cVector3d &a_vector2)
This function computes the addition of two vectors.
Definition: CMaths.h:708
cVector3d cProjectPointOnSegment(const cVector3d &a_point, const cVector3d &a_segmentPointA, const cVector3d &a_segmentPointB)
This function computes the projection of a point onto a segment.
Definition: CGeometry.h:299
int cSolveQuadric(double a_coefficient[3], double a_solution[2])
This function computes the solution of a quadric equation.
Definition: CPolySolver.h:121
void normalizer(cVector3d &a_result) const
This method normalizes this vector to length 1.
Definition: CVector3d.h:1086
double length() const
This method computes the Euclidean norm of this vector.
Definition: CVector3d.h:1015
cVector3d cSub(const cVector3d &a_vector1, const cVector3d &a_vector2)
This function computes the subtraction of two vectors.
Definition: CMaths.h:769
double cDistanceToLine(const cVector3d &a_point, const cVector3d &a_linePoint1, const cVector3d &a_linePoint2)
This function computes the distance between a point and a line.
Definition: CGeometry.h:501
void mul(const cMatrix3d &a_matrix)
This function computes the multiplication of this matrix with another.
Definition: CMatrix3d.h:883
void mulr(const double &a_scalar, cVector3d &a_result) const
This method computes the multiplication of this vector with a scalar.
Definition: CVector3d.h:739
cVector3d cProjectPointOnDiskXY(const cVector3d &a_point, const double &a_height, const double &a_radius)
This function computes the projection of a point onto a disk.
Definition: CGeometry.h:357
double cTriangleArea(const cVector3d &a_vertex0, const cVector3d &a_vertex1, const cVector3d &a_vertex2)
This function computes the area of a triangle.
Definition: CGeometry.h:89
double cDistanceSq(const cVector3d &a_point1, const cVector3d &a_point2)
This function computes the squared distance between two points.
Definition: CMaths.h:975
bool cBoxContains(const cVector3d &a_point, const cVector3d &a_boxMin, const cVector3d &a_boxMax)
This function checks if a point is contained in a box.
Definition: CGeometry.h:564
int cIntersectionSegmentTorus(const cVector3d &a_segmentPointA, const cVector3d &a_segmentPointB, const double &a_innerRadius, const double &a_outerRadius, cVector3d &a_collisionPoint, cVector3d &a_collisionNormal)
This function computes the nearest intersection point between a segment and a torus.
Definition: CGeometry.h:1561
This class implements a 3D matrix.
Definition: CMatrix3d.h:97
void negate()
This method computes the negated vector.
Definition: CVector3d.h:900
int cSolveLinear(double a_coefficient[2], double a_solution[1])
This function computes the solution of a linear equation.
Definition: CPolySolver.h:91
int cIntersectionSegmentEllipsoid(const cVector3d &a_segmentPointA, const cVector3d &a_segmentPointB, const cVector3d &a_pos, const double &a_radiusX, const double &a_radiusY, const double &a_radiusZ, cVector3d &a_collisionPoint0, cVector3d &a_collisionNormal0, cVector3d &a_collisionPoint1, cVector3d &a_collisionNormal1)
This function computes the intersection between a segment and a sphere.
Definition: CGeometry.h:928
cVector3d cMul(const double &a_value, const cVector3d &a_vector)
This function computes the multiplication of a vector by a scalar.
Definition: CMaths.h:824
double lengthsq() const
This method computes the squared value of the Euclidean norm of this vector.
Definition: CVector3d.h:1033
int cIntersectionSegmentToplessCylinder(const cVector3d &a_segmentPointA, const cVector3d &a_segmentPointB, const cVector3d &a_cylinderPointA, const cVector3d &a_cylinderPointB, const double &a_cylinderRadius, cVector3d &a_collisionPoint0, cVector3d &a_collisionNormal0, double &a_collisionPointRelPosAB0, cVector3d &a_collisionPoint1, cVector3d &a_collisionNormal1, double &a_collisionPointRelPosAB1)
This function computes the intersection between a segment and a topless cylinder. ...
Definition: CGeometry.h:1107
double cDot(const cVector3d &a_vector1, const cVector3d &a_vector2)
This function computes the dot product between two vectors.
Definition: CMaths.h:909
void set(const double &a_value)
This method initializes all elements of this matrix with an input value.
Definition: CMatrix3d.h:345
Implements polynomial solvers.
cVector3d cProjectPointOnTriangle(const cVector3d &a_point, const cVector3d &a_vertex0, const cVector3d &a_vertex1, const cVector3d &a_vertex2)
This function computes the projection of a point onto a triangle.
Definition: CGeometry.h:394
void cSwap(T &a_value1, T &a_value2)
This function swaps two elements.
Definition: CMaths.h:309
cVector3d cProjectPointOnPlane(const cVector3d &a_point, const cVector3d &a_planePoint, const cVector3d &a_planeNormal)
This function computes the projection of a point onto a plane.
Definition: CGeometry.h:117
bool cIntersectionSegmentTriangle(const cVector3d &a_segmentPointA, const cVector3d &a_segmentPointB, const cVector3d &a_triangleVertex0, const cVector3d &a_triangleVertex1, const cVector3d &a_triangleVertex2, const bool a_reportFrontSideCollision, const bool a_reportBackSideCollision, cVector3d &a_collisionPoint, cVector3d &a_collisionNormal, double &a_collisionPosVertex01, double &a_collisionPosVertex02)
This function computes the intersection between a segment and a triangle.
Definition: CGeometry.h:1668
cVector3d cNormalize(const cVector3d &a_vector)
This function computes the normalized vector.
Definition: CMaths.h:930
double cSqr(const double &a_value)
This function computes the square of a scalar.
Definition: CMaths.h:454
bool cContains(const T &a_value, const V &a_low, const V &a_high)
This function checks whether a value is within a specified range.
Definition: CMaths.h:429
void subr(const cVector3d &a_vector, cVector3d &a_result) const
This method computes the subtraction of this vector with another.
Definition: CVector3d.h:622
int cIntersectionSegmentCylinder(const cVector3d &a_segmentPointA, const cVector3d &a_segmentPointB, const double &a_baseRadius, const double &a_topRadius, const double &a_height, cVector3d &a_collisionPoint, cVector3d &a_collisionNormal)
This function computes the nearest intersection point between a segment and a cylinder.
Definition: CGeometry.h:1288
const double C_LARGE
Biggest value for a double.
Definition: CConstants.h:109
T cMin(const T &a_value1, const T &a_value2)
This function computes the minimum value between two values.
Definition: CMaths.h:242
cVector3d cNegate(const cVector3d &a_vector)
This function computes the negated vector.
Definition: CMaths.h:797
cVector3d cCross(const cVector3d &a_vector1, const cVector3d &a_vector2)
This function computes the cross product between two vectors.
Definition: CMaths.h:881
void mul(const double &a_scalar)
This method computes the multiplication of this vector with a scalar.
Definition: CVector3d.h:680
double dot(const cVector3d &a_vector) const
This method computes the dot product between this vector and another.
Definition: CVector3d.h:998
Definition: CAudioBuffer.cpp:56
int cIntersectionSegmentDisk(const cVector3d &a_segmentPointA, const cVector3d &a_segmentPointB, const cVector3d &a_diskPos, const cVector3d &a_diskNormal, const double &a_diskRadius, cVector3d &a_collisionPoint, cVector3d &a_collisionNormal)
This function computes the intersection between a segment and a disk.
Definition: CGeometry.h:700
int cIntersectionSegmentBox(const cVector3d &a_segmentPointA, const cVector3d &a_segmentPointB, const cVector3d &a_boxMin, const cVector3d &a_boxMax, cVector3d &a_collisionPoint, cVector3d &a_collisionNormal)
This function computes the nearest intersection point between a segment and a box.
Definition: CGeometry.h:1448
void add(const cVector3d &a_vector)
This method computes the addition of this vector with another.
Definition: CVector3d.h:452
bool cZero(const double &a_value)
This function checks if a value is equal to or almost near zero.
Definition: CMaths.h:153
int cIntersectionSegmentSphere(const cVector3d &a_segmentPointA, const cVector3d &a_segmentPointB, const cVector3d &a_spherePos, const double &a_sphereRadius, cVector3d &a_collisionPoint0, cVector3d &a_collisionNormal0, cVector3d &a_collisionPoint1, cVector3d &a_collisionNormal1)
This function computes the intersection between a segment and a sphere.
Definition: CGeometry.h:768