]>
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_
15 #include <Moof/Contact.hh>
16 #include <Moof/Drawable.hh>
17 #include <Moof/Log.hh>
18 #include <Moof/Math.hh>
19 #include <Moof/OpenGL.hh>
20 #include <Moof/Ray.hh>
21 #include <Moof/Shape.hh>
22 #include <Moof/Sphere.hh>
23 #include <Moof/Texture.hh>
30 struct Line
: public Drawable
, public Shape
<D
>
32 typedef cml::vector
< Scalar
, cml::fixed
<D
> > Vector
;
40 Line(const Vector
& point1
, const Vector
& point2
) :
45 Vector
getDirection() const
50 Scalar
getLength() const
52 return getDirection().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]) * (a
[1] - other
.a
[1]) -
65 (other
.b
[1] - other
.a
[1]) * (a
[0] - other
.a
[0])) / d
;
67 Scalar n
= ((b
[0] - a
[0]) * (b
[1] - other
.a
[1]) -
68 (b
[1] - a
[1]) * (b
[0] - other
.a
[0])) / d
;
70 if (m
< SCALAR(0.0) || m
> SCALAR(1.0) || // not intersecting
71 n
< SCALAR(0.0) || n
> SCALAR(1.0)) return false;
73 Vector2 tangent
= b
- a
;
74 Vector2 normal
= cml::perp(tangent
).normalize();
76 if (cml::dot(normal
, other
.a
- other
.b
) < SCALAR(0.0))
81 hit
.point
= a
+ m
* tangent
;
83 hit
.distance
= (other
.b
- hit
.point
).length();
88 bool intersect(const Sphere
<D
>& other
, Contact
<D
>& hit
) const
90 Vector surface
= b
- a
;
91 Vector toPoint
= other
.point
- a
;
93 Scalar surfaceLength
= surface
.length();
96 Scalar projection
= cml::dot(surface
, toPoint
);
98 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
;
118 Vector point
= a
+ surface
* projection
;
119 Vector normal
= other
.point
- point
;
121 Scalar distance
= normal
.length();
123 if (distance
> other
.radius
) false; // not intersecting
127 hit
.distance
= other
.radius
- distance
;
135 bool intersectRay(const Ray
<2>& ray
, Ray
<2>::Contact
& hit
) const
137 Vector2 v1
= a
- ray
.point
;
138 Scalar a1
= cml::signed_angle_2D(v1
, b
- ray
.point
);
140 //logWarning << "angle:::::::::: " << a1 << std::endl;
142 if (a1
== Constants::pi())
144 hit
.distance
= 5.4321;
147 else if (a1
== SCALAR(0.0))
149 hit
.distance
= 99999.0;
153 Scalar a2
= cml::signed_angle_2D(v1
, ray
.direction
);
155 if (a2
< SCALAR(0.0) || a2
> a1
) return false;
157 //hit.distance = 1.23456;
158 //hit.normal = Vector2(0.0, 0.0);
160 Vector2 n
= (b
- a
).normalize();
161 Scalar z
= cml::dot(ray
.point
- a
, n
);
162 Vector2 p
= a
+ n
* z
;
163 hit
.distance
= (ray
.point
- p
).length();
164 hit
.normal
= cml::perp(a
- b
);
169 // solve: Cx + r*Dx = Ax + s(Bx - Ax)
170 // Cy + r*Dy = Ay + s(By - Ay)
171 // where: 0 <= s <= 1 if intersection
177 Scalar denom = ray.direction[0] * (b[1] - a[1]) +
178 ray.direction[1] * (a[0] - b[0]);
180 // check if the ray and line are parallel
181 //if (isEqual(denom, SCALAR(0.0)))
182 if (denom == SCALAR(0.0))
184 Scalar numer = a[0] * (ray.point[1] - b[1]) +
185 b[0] * (a[1] - ray.point[1]) +
186 ray.point[0] * (b[1] - a[1]);
188 // check if they are collinear
189 if (isEqual(numer, SCALAR(0.0)))
191 hit.distance = SCALAR(0.0);
192 hit.normal.set(0.0, 0.0);
199 Scalar s = (ray.direction[0] * (ray.point[1] - a[1]) +
200 ray.direction[1] * (a[0] - ray.point[0])) / denom;
202 // check if the ray hits the segment
203 if (s < SCALAR(0.0) || s > SCALAR(1.0)) return false;
205 hit.distance = -(a[0] * (ray.point[1] - b[1]) +
206 b[0] * (a[1] - ray.point[1]) +
207 ray.point[0] * (b[1] - a[1])) / denom;
209 // check if the intersection is behind the ray
210 if (hit.distance < SCALAR(0.0)) return false;
212 Vector normal = cml::perp(a - b);
213 if (cml::dot(a - ray.point, normal) < 0) hit.normal = normal;
214 else hit.normal = -normal;
220 void draw(Scalar alpha
= 0.0) const
222 Mf::Texture::resetBind();
231 typedef Line
<2> Line2
;
232 typedef Line
<3> Line3
;
235 template <int D
, int N
>
236 struct Polygon
: public Drawable
, public Shape
<D
>
238 typedef cml::vector
< Scalar
, cml::fixed
<D
> > Vector
;
244 bool intersectRay(const Ray
<D
>& ray
, typename Ray
<D
>::Contact
& hit
)
249 void draw(Scalar alpha
= 0.0) const
251 Mf::Texture::resetBind();
253 for (int i
= 0; i
< D
; ++i
)
262 typedef Polygon
<2,3> Triangle2
;
263 typedef Polygon
<3,3> Triangle3
;
267 bool intersect(const Line
<D
>& line
, const Sphere
<D
>& sphere
,
276 #endif // _MOOF_LINE_HH_
This page took 0.04556 seconds and 5 git commands to generate.