]>
Dogcows Code - chaz/yoink/blob - src/moof/line.hh
2 /*] Copyright (c) 2009-2011, Charles McGarvey [*****************************
3 **] All rights reserved.
5 * Distributable under the terms and conditions of the 2-clause BSD license;
6 * see the file COPYING for a complete text of the license.
8 *****************************************************************************/
10 #ifndef _MOOF_LINE_HH_
11 #define _MOOF_LINE_HH_
15 * Classes related to line segments.
18 #include <moof/contact.hh>
19 #include <moof/drawable.hh>
20 #include <moof/image.hh>
21 #include <moof/log.hh>
22 #include <moof/math.hh>
23 #include <moof/opengl.hh>
24 #include <moof/ray.hh>
25 #include <moof/shape.hh>
26 #include <moof/sphere.hh>
33 struct line
: public drawable
, public shape
<D
>
35 typedef moof::vector
< scalar
, fixed
<D
> > vector
;
42 line(const vector
& point1
, const vector
& point2
) :
46 vector
direction() const
53 return direction().length();
56 bool intersect(const line
& other
, contact
<D
>& hit
) const
58 scalar d
= (other
.b
[1] - other
.a
[1]) * (b
[0] - a
[0]) -
59 (other
.b
[0] - other
.a
[0]) * (b
[1] - a
[1]);
61 if (d
== SCALAR(0.0)) return false; // lines are parallel
62 // ignoring the (somewhat remote) possibility of coincidence
64 scalar m
= ((other
.b
[0] - other
.a
[0]) *
66 (other
.b
[1] - other
.a
[1]) *
67 (a
[0] - other
.a
[0])) / d
;
69 scalar n
= ((b
[0] - a
[0]) * (b
[1] - other
.a
[1]) -
70 (b
[1] - a
[1]) * (b
[0] - other
.a
[0])) / d
;
72 if (m
< SCALAR(0.0) || m
> SCALAR(1.0) || // not intersecting
73 n
< SCALAR(0.0) || n
> SCALAR(1.0))
76 vector2 tangent
= b
- a
;
77 vector2 normal
= perp(tangent
).normalize();
79 if (dot(normal
, other
.a
- other
.b
) < SCALAR(0.0))
82 hit
.point
= a
+ m
* tangent
;
84 hit
.distance
= (other
.b
- hit
.point
).length();
89 bool intersect(const sphere
<D
>& other
, contact
<D
>& hit
) const
91 vector surface
= b
- a
;
92 vector toPoint
= other
.point
- a
;
94 scalar surfaceLength
= surface
.length();
97 scalar projection
= dot(surface
, toPoint
);
99 if (projection
< SCALAR(0.0) || projection
> surfaceLength
)
102 if (other
.intersect(a
, hit
))
104 hit
.normal
= -hit
.normal
;
108 else if (other
.intersect(b
, hit
))
110 hit
.normal
= -hit
.normal
;
117 vector point
= a
+ surface
* projection
;
118 vector normal
= other
.point
- point
;
120 scalar distance
= normal
.length();
122 if (distance
> other
.radius
) false; // not intersecting
126 hit
.distance
= other
.radius
- distance
;
134 intersect_ray(const ray
<2>& ray
, moof::ray
<2>::contact
& hit
) const
136 vector2 v1
= a
- ray
.point
;
137 scalar a1
= signed_angle_2D(v1
, b
- ray
.point
);
139 //log_warning << "angle:::::::::: " << a1 << std::endl;
141 if (a1
== constants::pi())
143 hit
.distance
= 5.4321;
146 else if (a1
== SCALAR(0.0))
148 hit
.distance
= 99999.0;
152 scalar a2
= signed_angle_2D(v1
, ray
.direction
);
154 if (a2
< SCALAR(0.0) || a2
> a1
) return false;
156 //hit.distance = 1.23456;
157 //hit.normal = vector2(0.0, 0.0);
159 vector2 n
= (b
- a
).normalize();
160 scalar z
= dot(ray
.point
- a
, n
);
161 vector2 p
= a
+ n
* z
;
162 hit
.distance
= (ray
.point
- p
).length();
163 hit
.normal
= perp(a
- b
);
167 // solve: Cx + r*Dx = Ax + s(Bx - Ax)
168 // Cy + r*Dy = Ay + s(By - Ay)
169 // where: 0 <= s <= 1 if intersection
175 scalar denom = ray.direction[0] * (b[1] - a[1]) +
176 ray.direction[1] * (a[0] - b[0]);
178 // check if the ray and line are parallel
179 //if (is_equal(denom, SCALAR(0.0)))
180 if (denom == SCALAR(0.0))
182 scalar numer = a[0] * (ray.point[1] - b[1]) +
183 b[0] * (a[1] - ray.point[1]) +
184 ray.point[0] * (b[1] - a[1]);
186 // check if they are collinear
187 if (is_equal(numer, SCALAR(0.0)))
189 hit.distance = SCALAR(0.0);
190 hit.normal.set(0.0, 0.0);
197 scalar s = (ray.direction[0] * (ray.point[1] - a[1]) +
198 ray.direction[1] * (a[0] - ray.point[0])) / denom;
200 // check if the ray hits the segment
201 if (s < SCALAR(0.0) || s > SCALAR(1.0)) return false;
203 hit.distance = -(a[0] * (ray.point[1] - b[1]) +
204 b[0] * (a[1] - ray.point[1]) +
205 ray.point[0] * (b[1] - a[1])) / denom;
207 // check if the intersection is behind the ray
208 if (hit.distance < SCALAR(0.0)) return false;
210 vector normal = perp(a - b);
211 if (dot(a - ray.point, normal) < 0) hit.normal = normal;
212 else hit.normal = -normal;
217 void draw(scalar alpha
= 0.0) const
219 image::reset_binding();
227 typedef line
<2> line2
;
228 typedef line
<3> line3
;
231 template <int D
, int N
>
232 struct polygon
: public drawable
, public shape
<D
>
234 typedef moof::vector
< scalar
, fixed
<D
> > vector
;
240 bool intersect_ray(const ray
<D
>& ray
,
241 typename
moof::ray
<D
>::contact
& hit
)
246 void draw(scalar alpha
= 0.0) const
248 image::reset_binding();
250 for (int i
= 0; i
< D
; ++i
) glVertex(points
[0]);
255 typedef polygon
<2,3> triangle2
;
256 typedef polygon
<3,3> triangle3
;
260 bool intersect(const line
<D
>& line
, const sphere
<D
>& sphere
, contact
<D
>& hit
)
268 #endif // _MOOF_LINE_HH_
This page took 0.044793 seconds and 5 git commands to generate.