1 | #include <gfx/std.h>
|
---|
2 | #include <gfx/math/random.h>
|
---|
3 | #include <gfx/geom/3D.h>
|
---|
4 |
|
---|
5 | using namespace simplif;
|
---|
6 |
|
---|
7 | Vec3 randomPoint(const Vec3& v1, const Vec3& v2)
|
---|
8 | {
|
---|
9 | real a = random1();
|
---|
10 |
|
---|
11 | return a*v1 + (1-a)*v2;
|
---|
12 | }
|
---|
13 |
|
---|
14 | Vec3 randomPoint(const Vec3& v1, const Vec3& v2, const Vec3& v3)
|
---|
15 | {
|
---|
16 | real b1 = 1 - sqrt( 1-random1() );
|
---|
17 | real b2 = (1-b1) * random1();
|
---|
18 | real b3 = 1 - b1 - b2;
|
---|
19 |
|
---|
20 | return b1*v1 + b2*v2 + b3*v3;
|
---|
21 | }
|
---|
22 |
|
---|
23 | real simplif::triangleArea(const Vec3& v1, const Vec3& v2, const Vec3& v3)
|
---|
24 | {
|
---|
25 | Vec3 a = v2 - v1;
|
---|
26 | Vec3 b = v3 - v1;
|
---|
27 |
|
---|
28 | return 0.5 * length(a ^ b);
|
---|
29 | }
|
---|
30 |
|
---|
31 | #define ROOT3 1.732050807568877
|
---|
32 | #define FOUR_ROOT3 6.928203230275509
|
---|
33 |
|
---|
34 | real triangleCompactness(const Vec3& v1, const Vec3& v2, const Vec3& v3)
|
---|
35 | {
|
---|
36 | real L1 = norm2(v2-v1);
|
---|
37 | real L2 = norm2(v3-v2);
|
---|
38 | real L3 = norm2(v1-v3);
|
---|
39 |
|
---|
40 | return FOUR_ROOT3 * simplif::triangleArea(v1,v2,v3) / (L1+L2+L3);
|
---|
41 | }
|
---|
42 |
|
---|
43 |
|
---|
44 |
|
---|
45 | ////////////////////////////////////////////////////////////////////////.
|
---|
46 | //
|
---|
47 | // class: Bounds
|
---|
48 | //
|
---|
49 |
|
---|
50 | void Bounds::reset()
|
---|
51 | {
|
---|
52 | min[X] = min[Y] = min[Z] = HUGE;
|
---|
53 | max[X] = max[Y] = max[Z] = -HUGE;
|
---|
54 |
|
---|
55 | center[X] = center[Y] = center[Z] = 0.0;
|
---|
56 | radius = 0.0;
|
---|
57 |
|
---|
58 | points = 0;
|
---|
59 | }
|
---|
60 |
|
---|
61 | void Bounds::addPoint(const Vec3& v)
|
---|
62 | {
|
---|
63 | if( v[X] < min[X] ) min[X] = v[X];
|
---|
64 | if( v[Y] < min[Y] ) min[Y] = v[Y];
|
---|
65 | if( v[Z] < min[Z] ) min[Z] = v[Z];
|
---|
66 |
|
---|
67 | if( v[X] > max[X] ) max[X] = v[X];
|
---|
68 | if( v[Y] > max[Y] ) max[Y] = v[Y];
|
---|
69 | if( v[Z] > max[Z] ) max[Z] = v[Z];
|
---|
70 |
|
---|
71 |
|
---|
72 | center += v;
|
---|
73 |
|
---|
74 | points++;
|
---|
75 | }
|
---|
76 |
|
---|
77 | void Bounds::complete()
|
---|
78 | {
|
---|
79 | center /= (real)points;
|
---|
80 |
|
---|
81 | Vec3 R1 = max-center;
|
---|
82 | Vec3 R2 = min-center;
|
---|
83 |
|
---|
84 | radius = MAX(length(R1), length(R2));
|
---|
85 | }
|
---|
86 |
|
---|
87 | ////////////////////////////////////////////////////////////////////////
|
---|
88 | //
|
---|
89 | // class: Plane
|
---|
90 | //
|
---|
91 |
|
---|
92 | void Plane::calcFrom(const Vec3& p1, const Vec3& p2, const Vec3& p3)
|
---|
93 | {
|
---|
94 | Vec3 v1 = p2-p1;
|
---|
95 | Vec3 v2 = p3-p1;
|
---|
96 |
|
---|
97 | n = v1 ^ v2;
|
---|
98 | unitize(n);
|
---|
99 |
|
---|
100 | d = -n*p1;
|
---|
101 | }
|
---|
102 |
|
---|
103 | void Plane::calcFrom(const array<Vec3>& verts)
|
---|
104 | {
|
---|
105 | n[X] = n[Y] = n[Z] = 0.0;
|
---|
106 |
|
---|
107 | int i;
|
---|
108 | for(i=0; i<verts.length()-1; i++)
|
---|
109 | {
|
---|
110 | const Vec3& cur = verts[i];
|
---|
111 | const Vec3& next = verts[i+1];
|
---|
112 |
|
---|
113 | n[X] += (cur[Y] - next[Y]) * (cur[Z] + next[Z]);
|
---|
114 | n[Y] += (cur[Z] - next[Z]) * (cur[X] + next[X]);
|
---|
115 | n[Z] += (cur[X] - next[X]) * (cur[Y] + next[Y]);
|
---|
116 | }
|
---|
117 |
|
---|
118 | const Vec3& cur = verts[verts.length()-1];
|
---|
119 | const Vec3& next = verts[0];
|
---|
120 | n[X] += (cur[Y] - next[Y]) * (cur[Z] + next[Z]);
|
---|
121 | n[Y] += (cur[Z] - next[Z]) * (cur[X] + next[X]);
|
---|
122 | n[Z] += (cur[X] - next[X]) * (cur[Y] + next[Y]);
|
---|
123 |
|
---|
124 | unitize(n);
|
---|
125 |
|
---|
126 | d = -n*verts[0];
|
---|
127 | }
|
---|
128 |
|
---|
129 |
|
---|
130 |
|
---|
131 | ////////////////////////////////////////////////////////////////////////
|
---|
132 | //
|
---|
133 | // class: Face3
|
---|
134 | //
|
---|
135 |
|
---|
136 | real Face3::area()
|
---|
137 | {
|
---|
138 | return triangleArea(vertexPos(0),vertexPos(1),vertexPos(2));
|
---|
139 | }
|
---|
140 |
|
---|
141 |
|
---|
142 | //
|
---|
143 | // Use Anoop's distance code
|
---|
144 | //
|
---|
145 |
|
---|
146 | extern real __gfx_hoppe_dist(const Face3& f, const Vec3& v);
|
---|
147 |
|
---|
148 | real Face3::distTo(const Vec3& v) const
|
---|
149 | {
|
---|
150 | return __gfx_hoppe_dist(*this, v);
|
---|
151 | }
|
---|