]> Dogcows Code - chaz/yoink/blob - src/moof/line.hh
bugfix: win32 packaging script temp directories
[chaz/yoink] / src / moof / line.hh
1
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
4 *
5 * vi:ts=4 sw=4 tw=75
6 *
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.
9 *
10 **************************************************************************/
11
12 #ifndef _MOOF_LINE_HH_
13 #define _MOOF_LINE_HH_
14
15 /**
16 * \file line.hh
17 * Classes related to line segments.
18 */
19
20 #include <moof/contact.hh>
21 #include <moof/drawable.hh>
22 #include <moof/log.hh>
23 #include <moof/math.hh>
24 #include <moof/opengl.hh>
25 #include <moof/ray.hh>
26 #include <moof/shape.hh>
27 #include <moof/sphere.hh>
28 #include <moof/texture.hh>
29
30
31 namespace moof {
32
33
34 template <int D>
35 struct line : public drawable, public shape<D>
36 {
37 typedef moof::vector< scalar, fixed<D> > vector;
38
39
40 vector a;
41 vector b;
42
43
44 line() {}
45
46 line(const vector& point1, const vector& point2) :
47 a(point1),
48 b(point2) {}
49
50
51 vector direction() const
52 {
53 return b - a;
54 }
55
56 scalar length() const
57 {
58 return direction().length();
59 }
60
61
62 bool intersect(const line& other, contact<D>& hit) const
63 {
64 scalar d = (other.b[1] - other.a[1]) * (b[0] - a[0]) -
65 (other.b[0] - other.a[0]) * (b[1] - a[1]);
66
67 if (d == SCALAR(0.0)) return false; // lines are parallel
68 // ignoring the (somewhat remote) possibility of coincidence
69
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;
72
73 scalar n = ((b[0] - a[0]) * (b[1] - other.a[1]) -
74 (b[1] - a[1]) * (b[0] - other.a[0])) / d;
75
76 if (m < SCALAR(0.0) || m > SCALAR(1.0) || // not intersecting
77 n < SCALAR(0.0) || n > SCALAR(1.0)) return false;
78
79 vector2 tangent = b - a;
80 vector2 normal = perp(tangent).normalize();
81
82 if (dot(normal, other.a - other.b) < SCALAR(0.0))
83 {
84 normal = -normal;
85 }
86
87 hit.point = a + m * tangent;
88 hit.normal = normal;
89 hit.distance = (other.b - hit.point).length();
90
91 return true;
92 }
93
94 bool intersect(const sphere<D>& other, contact<D>& hit) const
95 {
96 vector surface = b - a;
97 vector toPoint = other.point - a;
98
99 scalar surfaceLength = surface.length();
100 surface.normalize();
101
102 scalar projection = dot(surface, toPoint);
103
104 if (projection < SCALAR(0.0) || projection > surfaceLength)
105 {
106 // try endpoints
107
108 if (other.intersect(a, hit))
109 {
110 hit.normal = -hit.normal;
111 hit.point = a;
112 return true;
113 }
114 else if (other.intersect(b, hit))
115 {
116 hit.normal = -hit.normal;
117 hit.point = b;
118 return true;
119 }
120
121 return false;
122 }
123
124 vector point = a + surface * projection;
125 vector normal = other.point - point;
126
127 scalar distance = normal.length();
128
129 if (distance > other.radius) false; // not intersecting
130
131 normal.normalize();
132
133 hit.distance = other.radius - distance;
134 hit.point = point;
135 hit.normal = normal;
136
137 return true;
138 }
139
140
141 bool intersect_ray(const ray<2>& ray, ray<2>::contact& hit) const
142 {
143 vector2 v1 = a - ray.point;
144 scalar a1 = signed_angle_2D(v1, b - ray.point);
145
146 //log_warning << "angle:::::::::: " << a1 << std::endl;
147
148 if (a1 == constants::pi())
149 {
150 hit.distance = 5.4321;
151 return true;
152 }
153 else if (a1 == SCALAR(0.0))
154 {
155 hit.distance = 99999.0;
156 return true;
157 }
158
159 scalar a2 = signed_angle_2D(v1, ray.direction);
160
161 if (a2 < SCALAR(0.0) || a2 > a1) return false;
162
163 //hit.distance = 1.23456;
164 //hit.normal = vector2(0.0, 0.0);
165
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);
171 return true;
172
173
174 /*
175 // solve: Cx + r*Dx = Ax + s(Bx - Ax)
176 // Cy + r*Dy = Ay + s(By - Ay)
177 // where: 0 <= s <= 1 if intersection
178 // given: A = a
179 // B = b
180 // C = ray.point
181 // D = ray.direction
182
183 scalar denom = ray.direction[0] * (b[1] - a[1]) +
184 ray.direction[1] * (a[0] - b[0]);
185
186 // check if the ray and line are parallel
187 //if (is_equal(denom, SCALAR(0.0)))
188 if (denom == SCALAR(0.0))
189 {
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]);
193
194 // check if they are collinear
195 if (is_equal(numer, SCALAR(0.0)))
196 {
197 hit.distance = SCALAR(0.0);
198 hit.normal.set(0.0, 0.0);
199 return true;
200 }
201
202 return false;
203 }
204
205 scalar s = (ray.direction[0] * (ray.point[1] - a[1]) +
206 ray.direction[1] * (a[0] - ray.point[0])) / denom;
207
208 // check if the ray hits the segment
209 if (s < SCALAR(0.0) || s > SCALAR(1.0)) return false;
210
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;
214
215 // check if the intersection is behind the ray
216 if (hit.distance < SCALAR(0.0)) return false;
217
218 vector normal = perp(a - b);
219 if (dot(a - ray.point, normal) < 0) hit.normal = normal;
220 else hit.normal = -normal;
221 return true;
222 */
223 }
224
225
226 void draw(scalar alpha = 0.0) const
227 {
228 texture::reset_binding();
229 glBegin(GL_LINES);
230 glVertex(a);
231 glVertex(b);
232 glEnd();
233 }
234 };
235
236
237 typedef line<2> line2;
238 typedef line<3> line3;
239
240
241 template <int D, int N>
242 struct polygon : public drawable, public shape<D>
243 {
244 typedef moof::vector< scalar, fixed<D> > vector;
245
246 vector points[N];
247
248 polygon() {}
249
250 bool intersect_ray(const ray<D>& ray, typename ray<D>::contact& hit)
251 {
252 return false;
253 }
254
255 void draw(scalar alpha = 0.0) const
256 {
257 texture::reset_binding();
258 glBegin(GL_POLYGON);
259 for (int i = 0; i < D; ++i)
260 {
261 glVertex(points[0]);
262 }
263 glEnd();
264 }
265 };
266
267
268 typedef polygon<2,3> triangle2;
269 typedef polygon<3,3> triangle3;
270
271
272 template <int D>
273 bool intersect(const line<D>& line, const sphere<D>& sphere,
274 contact<D>& hit)
275 {
276 return false;
277 }
278
279
280 } // namespace moof
281
282 #endif // _MOOF_LINE_HH_
283
This page took 0.040796 seconds and 4 git commands to generate.