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