]>
Dogcows Code - chaz/yoink/blob - src/moof/line.hh
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
10 **************************************************************************/
12 #ifndef _MOOF_LINE_HH_
13 #define _MOOF_LINE_HH_
17 * Classes related to line segments.
20 #include <moof/contact.hh>
21 #include <moof/drawable.hh>
22 #include <moof/image.hh>
23 #include <moof/log.hh>
24 #include <moof/math.hh>
25 #include <moof/opengl.hh>
26 #include <moof/ray.hh>
27 #include <moof/shape.hh>
28 #include <moof/sphere.hh>
35 struct line
: public drawable
, public shape
<D
>
37 typedef moof::vector
< scalar
, fixed
<D
> > vector
;
46 line(const vector
& point1
, const vector
& point2
) :
51 vector
direction() const
58 return direction().length();
62 bool intersect(const line
& other
, contact
<D
>& hit
) const
64 scalar d
= (other
.b
[1] - other
.a
[1]) * (b
[0] - a
[0]) -
65 (other
.b
[0] - other
.a
[0]) * (b
[1] - a
[1]);
67 if (d
== SCALAR(0.0)) return false; // lines are parallel
68 // ignoring the (somewhat remote) possibility of coincidence
70 scalar m
= ((other
.b
[0] - other
.a
[0]) * (a
[1] - other
.a
[1]) -
71 (other
.b
[1] - other
.a
[1]) * (a
[0] - other
.a
[0])) / d
;
73 scalar n
= ((b
[0] - a
[0]) * (b
[1] - other
.a
[1]) -
74 (b
[1] - a
[1]) * (b
[0] - other
.a
[0])) / d
;
76 if (m
< SCALAR(0.0) || m
> SCALAR(1.0) || // not intersecting
77 n
< SCALAR(0.0) || n
> SCALAR(1.0)) return false;
79 vector2 tangent
= b
- a
;
80 vector2 normal
= perp(tangent
).normalize();
82 if (dot(normal
, other
.a
- other
.b
) < SCALAR(0.0))
87 hit
.point
= a
+ m
* tangent
;
89 hit
.distance
= (other
.b
- hit
.point
).length();
94 bool intersect(const sphere
<D
>& other
, contact
<D
>& hit
) const
96 vector surface
= b
- a
;
97 vector toPoint
= other
.point
- a
;
99 scalar surfaceLength
= surface
.length();
102 scalar projection
= dot(surface
, toPoint
);
104 if (projection
< SCALAR(0.0) || projection
> surfaceLength
)
108 if (other
.intersect(a
, hit
))
110 hit
.normal
= -hit
.normal
;
114 else if (other
.intersect(b
, hit
))
116 hit
.normal
= -hit
.normal
;
124 vector point
= a
+ surface
* projection
;
125 vector normal
= other
.point
- point
;
127 scalar distance
= normal
.length();
129 if (distance
> other
.radius
) false; // not intersecting
133 hit
.distance
= other
.radius
- distance
;
141 bool intersect_ray(const ray
<2>& ray
, moof::ray
<2>::contact
& hit
) const
143 vector2 v1
= a
- ray
.point
;
144 scalar a1
= signed_angle_2D(v1
, b
- ray
.point
);
146 //log_warning << "angle:::::::::: " << a1 << std::endl;
148 if (a1
== constants::pi())
150 hit
.distance
= 5.4321;
153 else if (a1
== SCALAR(0.0))
155 hit
.distance
= 99999.0;
159 scalar a2
= signed_angle_2D(v1
, ray
.direction
);
161 if (a2
< SCALAR(0.0) || a2
> a1
) return false;
163 //hit.distance = 1.23456;
164 //hit.normal = vector2(0.0, 0.0);
166 vector2 n
= (b
- a
).normalize();
167 scalar z
= dot(ray
.point
- a
, n
);
168 vector2 p
= a
+ n
* z
;
169 hit
.distance
= (ray
.point
- p
).length();
170 hit
.normal
= perp(a
- b
);
175 // solve: Cx + r*Dx = Ax + s(Bx - Ax)
176 // Cy + r*Dy = Ay + s(By - Ay)
177 // where: 0 <= s <= 1 if intersection
183 scalar denom = ray.direction[0] * (b[1] - a[1]) +
184 ray.direction[1] * (a[0] - b[0]);
186 // check if the ray and line are parallel
187 //if (is_equal(denom, SCALAR(0.0)))
188 if (denom == SCALAR(0.0))
190 scalar numer = a[0] * (ray.point[1] - b[1]) +
191 b[0] * (a[1] - ray.point[1]) +
192 ray.point[0] * (b[1] - a[1]);
194 // check if they are collinear
195 if (is_equal(numer, SCALAR(0.0)))
197 hit.distance = SCALAR(0.0);
198 hit.normal.set(0.0, 0.0);
205 scalar s = (ray.direction[0] * (ray.point[1] - a[1]) +
206 ray.direction[1] * (a[0] - ray.point[0])) / denom;
208 // check if the ray hits the segment
209 if (s < SCALAR(0.0) || s > SCALAR(1.0)) return false;
211 hit.distance = -(a[0] * (ray.point[1] - b[1]) +
212 b[0] * (a[1] - ray.point[1]) +
213 ray.point[0] * (b[1] - a[1])) / denom;
215 // check if the intersection is behind the ray
216 if (hit.distance < SCALAR(0.0)) return false;
218 vector normal = perp(a - b);
219 if (dot(a - ray.point, normal) < 0) hit.normal = normal;
220 else hit.normal = -normal;
226 void draw(scalar alpha
= 0.0) const
228 image::reset_binding();
237 typedef line
<2> line2
;
238 typedef line
<3> line3
;
241 template <int D
, int N
>
242 struct polygon
: public drawable
, public shape
<D
>
244 typedef moof::vector
< scalar
, fixed
<D
> > vector
;
250 bool intersect_ray(const ray
<D
>& ray
,
251 typename
moof::ray
<D
>::contact
& hit
)
256 void draw(scalar alpha
= 0.0) const
258 image::reset_binding();
260 for (int i
= 0; i
< D
; ++i
)
269 typedef polygon
<2,3> triangle2
;
270 typedef polygon
<3,3> triangle3
;
274 bool intersect(const line
<D
>& line
, const sphere
<D
>& sphere
,
283 #endif // _MOOF_LINE_HH_
This page took 0.053234 seconds and 4 git commands to generate.