Free Electron
RayCylinderIntersect.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __solve_RayCylinderIntersect_h__
8 #define __solve_RayCylinderIntersect_h__
9 
10 namespace fe
11 {
12 namespace ext
13 {
14 
15 /**************************************************************************//**
16  @brief Find intersection between ray and cylinder
17 
18  @ingroup solve
19 
20  "Intersecting a Ray with a Cylinder"
21  by Joseph M. Cychosz and Warren N. Waggenspack, Jr.,
22  (3ksnn64@ecn.purdue.edu, mewagg@mewnw.dnet.lsu.edu)
23  in "Graphics Gems IV", Academic Press, 1994
24 *//***************************************************************************/
25 template <typename T>
27 {
28  public:
29 static T solve(const Vector<3,T>& base,const Vector<3,T> axis,
30  const T radius,
31  const Vector<3,T>& origin,
32  const Vector<3,T>& direction,
33  T& along,
34  Vector<3,T>& intersection);
35 static void resolveContact(const Vector<3,T>& base,const Vector<3,T> axis,
36  const T radius,
37  const Vector<3,T>& origin,
38  const Vector<3,T>& direction,
39  const T range,const T along,
40  const Vector<3,T>& intersection,
41  Vector<3,T>& normal);
42 };
43 
44 // direction must be normalized
45 template <typename T>
47  const Vector<3,T>& base,const Vector<3,T> axis,T radius,
48  const Vector<3,T>& origin, const Vector<3,T>& direction,
49  T& along,Vector<3,T>& intersection)
50 {
51 // feLog("base %s axis %s radius %.6G\n",c_print(base),
52 // c_print(axis),radius);
53 // feLog("origin: %s\n",c_print(origin));
54 // feLog("direction: %s\n",c_print(direction));
55 
56  const Vector<3,T> RC=origin-base;
57  Vector<3,T> n;
58  cross3(n,direction,axis);
59  const T nlength=magnitude(n);
60  if(nlength<fe::tol)
61  {
62  return T(-1);
63  }
64 
65  n*=T(1)/nlength;
66  const T d=fabs(dot(RC,n)); // distance from axis
67  if(d>radius)
68  {
69  return T(-1);
70  }
71 
72  Vector<3,T> tmp;
73  cross3(tmp,RC,axis);
74  T t= -dot(tmp,n)/nlength;
75  cross3(tmp,n,axis);
76  normalize(tmp);
77  T range=t-fabs(sqrtf(radius*radius-d*d)/dot(direction,tmp));
78 
79  const T axislength2=magnitudeSquared(axis);
80  intersection=origin+range*direction;
81  along=dot(axis,intersection-base)/axislength2;
82 // feLog("intersection %s along %.6G range %.6G\n",
83 // c_print(intersection),along,range);
84 
85  return (along>0 && along<1.0f)? range: T(-1);
86 }
87 
88 // direction must be normalized
89 template <typename T>
91  const Vector<3,T>& base,const Vector<3,T> axis,T radius,
92  const Vector<3,T>& origin,const Vector<3,T>& direction,
93  const T range,const T along,
94  const Vector<3,T>& intersection,Vector<3,T>& normal)
95 {
96  Vector<3,T> centerAlong=base+axis*along;
97  normal=(intersection-centerAlong)/radius;
98 }
99 
100 } /* namespace ext */
101 } /* namespace fe */
102 
103 #endif /* __solve_RayCylinderIntersect_h__ */
kernel
Definition: namespace.dox:3
Find intersection between ray and cylinder.
Definition: RayCylinderIntersect.h:26