1 // Copyright 2002, 2004 David Hilvert <dhilvert@auricle.dyndns.org>,
2 // <dhilvert@ugcs.caltech.edu>
4 /* This file is part of the Anti-Lamenessing Engine.
6 The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with the Anti-Lamenessing Engine; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * Structure to describe a point in three dimensions.
38 point(ale_pos x0
, ale_pos x1
, ale_pos x2
) {
44 point(const point
&p
) {
50 static point
unit(int dimension
) {
52 return point(1, 0, 0);
54 return point(0, 1, 0);
56 return point(0, 0, 1);
61 static point
undefined() {
69 static point
posinf() {
75 assert (isinf(a
) && a
> 0);
77 return point(a
, a
, a
);
80 static point
neginf() {
83 assert (isinf(n
[0]) && n
[0] < 0);
88 void accumulate_max(point p
) {
89 for (int d
= 0; d
< 3; d
++)
94 void accumulate_min(point p
) {
95 for (int d
= 0; d
< 3; d
++)
100 int defined() const {
107 return (::finite(x
[0])
112 static int defined(const point
&p
) {
117 * Z-values of zero are almost never the right thing to do ...
119 point(d2::point p
, ale_pos z
= 0) {
125 const ale_pos
&operator[](int i
) const {
132 ale_pos
&operator[](int i
) {
139 d2::point
xy() const {
148 point
operator+(point p
) const {
149 return point(x
[0] + p
[0], x
[1] + p
[1], x
[2] + p
[2]);
152 point
operator-(point p
) const {
153 return point(x
[0] - p
[0], x
[1] - p
[1], x
[2] - p
[2]);
156 point
operator-() const {
157 return point(-x
[0], -x
[1], -x
[2]);
160 point
operator/(ale_pos r
) const {
161 return point(x
[0] / r
, x
[1] / r
, x
[2] / r
);
164 point
operator /=(ale_pos r
) {
172 point
operator *=(ale_pos r
) {
180 point
operator +=(point p
) {
188 point
operator -=(point p
) {
196 int operator !=(point p
) {
202 point
mult(ale_pos d
) const {
203 return point(x
[0] * d
, x
[1] * d
, x
[2] * d
);
206 point
operator*(point p
) const {
207 return point(x
[0] * p
[0], x
[1] * p
[1], x
[2] * p
[2]);
210 ale_pos
normsq() const {
211 return x
[0] * x
[0] + x
[1] * x
[1] + x
[2] * x
[2];
214 ale_pos
norm() const {
215 return sqrt(normsq());
218 point
normalize() const {
219 return operator/(norm());
222 ale_pos
lengthtosq(point p
) const {
223 point diff
= operator-(p
);
224 return diff
.normsq();
227 ale_pos
lengthto(point p
) const {
228 return sqrt(lengthtosq(p
));
231 ale_pos
anglebetw(point p
, point q
) {
233 * by the law of cosines, the cosine is equal to:
235 * (lengthtosq(p) + lengthtosq(q) - p.lengthtosq(q))
236 * / (2 * lengthto(p) * lengthto(q))
239 ale_pos to_p
= lengthtosq(p
);
240 ale_pos to_q
= lengthtosq(q
);
242 ale_pos cos_of
= (double) (to_p
+ to_q
- p
.lengthtosq(q
))
243 / (double) (2 * sqrt(to_p
) * sqrt(to_q
));
246 * XXX: is the fabs() required?
249 return fabs(acos(cos_of
));
254 * Determine the cross product
256 point
xproduct(point p
, point q
) {
263 return point(pp
[1] * qq
[2] - pp
[2] * qq
[1],
264 pp
[2] * qq
[0] - pp
[0] * qq
[2],
265 pp
[0] * qq
[1] - pp
[1] * qq
[0]);
269 * Determine the dot product
271 ale_pos
dproduct(const point
&p
) {
272 return x
[0] * p
[0] + x
[1] * p
[1] + x
[2] * p
[2];
276 * Determine whether the point is inside a given volume
278 int inside(const point
&min
, const point
&max
) {
279 for (int d
= 0; d
< 3; d
++) {
289 inline point
operator*(const point
&p
, double d
) {
292 inline point
operator*(double d
, const point
&p
) {