]> Dogcows Code - chaz/yoink/blob - src/Moof/Line.hh
f8a2b66111f34a6de84a480fe461cd118064b77e
[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 #include <Moof/Drawable.hh>
16 #include <Moof/Math.hh>
17 #include <Moof/OpenGL.hh>
18 #include <Moof/Ray.hh>
19 #include <Moof/Shape.hh>
20 #include <Moof/Texture.hh>
21
22
23 namespace Mf {
24
25
26 template <int D>
27 struct Line : public Drawable, public Shape<D>
28 {
29 typedef cml::vector< Scalar, cml::fixed<D> > Vector;
30
31 Vector a;
32 Vector b;
33
34
35 Line() {}
36
37 Line(const Vector& point1, const Vector& point2) :
38 a(point1),
39 b(point2) {}
40
41 bool intersectRay(const Ray<2>& ray, Ray<2>::Contact& hit) const
42 {
43 // solve: Cx + r*Dx = Ax + s(Bx - Ax)
44 // Cy + r*Dy = Ay + s(By - Ay)
45 // where: 0 <= s <= 1 if intersection
46 // given: A = a
47 // B = b
48 // C = ray.point
49 // D = ray.direction
50
51 Scalar denom = ray.direction[0] * (b[1] - a[1]) +
52 ray.direction[1] * (a[0] - b[0]);
53
54 // check if the ray and line are parallel
55 //if (isEqual(denom, SCALAR(0.0)))
56 if (denom == SCALAR(0.0))
57 {
58 Scalar numer = a[0] * (ray.point[1] - b[1]) +
59 b[0] * (a[1] - ray.point[1]) +
60 ray.point[0] * (b[1] - a[1]);
61
62 // check if they are collinear
63 if (isEqual(numer, SCALAR(0.0)))
64 {
65 hit.distance = SCALAR(0.0);
66 hit.normal.set(0.0, 0.0);
67 return true;
68 }
69
70 return false;
71 }
72
73 Scalar s = (ray.direction[0] * (ray.point[1] - a[1]) +
74 ray.direction[1] * (a[0] - ray.point[0])) / denom;
75
76 // check if the ray hits the segment
77 if (s < SCALAR(0.0) || s > SCALAR(1.0)) return false;
78
79 hit.distance = -(a[0] * (ray.point[1] - b[1]) +
80 b[0] * (a[1] - ray.point[1]) +
81 ray.point[0] * (b[1] - a[1])) / denom;
82
83 // check if the intersection is behind the ray
84 if (hit.distance < SCALAR(0.0)) return false;
85
86 Vector normal = cml::perp(a - b);
87 if (cml::dot(a - ray.point, normal) < 0) hit.normal = normal;
88 else hit.normal = -normal;
89 return true;
90 }
91
92 void draw(Scalar alpha = 0.0) const
93 {
94 Mf::Texture::resetBind();
95 glBegin(GL_LINES);
96 glVertex(a);
97 glVertex(b);
98 glEnd();
99 }
100 };
101
102
103 typedef Line<2> Line2;
104 typedef Line<3> Line3;
105
106
107 template <int D, int N>
108 struct Polygon : public Drawable, public Shape<D>
109 {
110 typedef cml::vector< Scalar, cml::fixed<D> > Vector;
111
112 Vector points[N];
113
114 Polygon() {}
115
116 bool intersectRay(const Ray<D>& ray, typename Ray<D>::Contact& hit)
117 {
118 return false;
119 }
120
121 void draw(Scalar alpha = 0.0) const
122 {
123 Mf::Texture::resetBind();
124 glBegin(GL_POLYGON);
125 for (int i = 0; i < D; ++i)
126 {
127 glVertex(points[0]);
128 }
129 glEnd();
130 }
131 };
132
133
134 typedef Polygon<2,3> Triangle2;
135 typedef Polygon<3,3> Triangle3;
136
137
138 } // namespace Mf
139
140 #endif // _MOOF_LINE_HH_
141
This page took 0.037252 seconds and 3 git commands to generate.