Mercurial > projects > doodle
annotate doodle/tk/geometry.d @ 136:752676232e4b
Port to GtkD-2.0 (gtk+3)
author | David Bryant <bagnose@gmail.com> |
---|---|
date | Wed, 26 Sep 2012 17:36:31 +0930 |
parents | bc5baa585b32 |
children |
rev | line source |
---|---|
28
1754cb773d41
Part-way through getting to compile with configure/builder.
Graham St Jack <graham.stjack@internode.on.net>
parents:
25
diff
changeset
|
1 module doodle.tk.geometry; |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
2 |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
3 private { |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
4 import std.stdio; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
5 import std.math; |
67 | 6 import doodle.core.misc; |
41 | 7 import doodle.core.logging; |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
8 } |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
9 |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
10 // In doodle x and y increase right/east and up/north respectively. |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
11 |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
12 // TODO explain the strategy for ensuring numerical stability |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
13 // and the division of responsibility between users of these |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
14 // types and the types themselves. |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
15 // |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
16 // Explain how numerical instability is handled. The current policy |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
17 // is to correct bad user input (eg a gradient with miniscule length) and |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
18 // print warnings rather than have assertions that cause crashes. |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
19 // |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
20 // There are no mutating operations other than opAssign |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
21 |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
22 // |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
23 // A location in 2D space |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
24 // |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
25 |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
26 struct Point { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
27 this(in double x, in double y) { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
28 _x = x; |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
29 _y = y; |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
30 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
31 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
32 Point opAdd(in Vector v) const { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
33 return Point(_x + v._x, _y + v._y); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
34 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
35 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
36 Point opSub(in Vector v) const { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
37 return Point(_x - v._x, _y - v._y); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
38 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
39 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
40 Vector opSub(in Point p) const { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
41 return Vector(_x - p._x, _y - p._y); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
42 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
43 |
62 | 44 string toString() { |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
45 return std.string.format("(%f, %f)", _x, _y); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
46 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
47 |
132 | 48 @property double x() const { return _x; } |
49 @property double y() const { return _y; } | |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
50 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
51 private { |
100 | 52 double _x = 0.0, _y = 0.0; |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
53 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
54 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
55 |
48 | 56 Point minExtents(in Point a, in Point b) { |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
57 return Point(min(a.x, b.x), min(a.y, b.y)); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
58 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
59 |
48 | 60 Point maxExtents(in Point a, in Point b) { |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
61 return Point(max(a.x, b.x), max(a.y, b.y)); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
62 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
63 |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
64 // |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
65 // The displacement between two locations in 2D space |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
66 // |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
67 |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
68 struct Vector { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
69 this(in double x, in double y) { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
70 _x = x; |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
71 _y = y; |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
72 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
73 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
74 Vector opAdd(in Vector v) const { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
75 return Vector(_x + v._x, _y + v._y); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
76 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
77 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
78 Vector opSub(in Vector v) const { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
79 return Vector(_x - v._x, _y - v._y); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
80 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
81 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
82 Vector opNeg() const { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
83 return Vector(-_x, -_y); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
84 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
85 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
86 Vector opMul_r(in double d) const { |
41 | 87 assert(!isnan(d)); |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
88 return Vector(d * _x, d * _y); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
89 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
90 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
91 Vector opDiv(in double d) const { |
41 | 92 assert(!isnan(d)); |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
93 return Vector(_x / d, _y / d); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
94 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
95 |
132 | 96 @property double length() const { |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
97 return sqrt(_x * _x + _y * _y); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
98 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
99 |
62 | 100 string toString() { |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
101 return std.string.format("[%f, %f]", _x, _y); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
102 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
103 |
132 | 104 @property double x() const { return _x; } |
105 @property double y() const { return _y; } | |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
106 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
107 private { |
100 | 108 double _x = 0.0, _y = 0.0; |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
109 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
110 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
111 |
79 | 112 /* |
113 Vector normal(in Vector v) { | |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
114 double l = v.length; |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
115 |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
116 if (l < 1e-9) { // TODO consolidate numerical stability constants |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
117 writefln("Warning: normalising tiny vector. Length: %f", l); |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
118 return Vector(1.0, 0.0); |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
119 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
120 else { |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
121 return v / l; |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
122 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
123 } |
79 | 124 */ |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
125 |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
126 // |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
127 // A rectangle in 2D space. |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
128 // Internally represented by: |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
129 // a point defining the bottom left corner |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
130 // a vector defining the displacement to the upper right corner |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
131 // |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
132 |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
133 struct Rectangle { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
134 /* |
66 | 135 static Rectangle from_arbitrary_corners(in Point corner1, in Point corner) { |
136 } | |
137 */ | |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
138 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
139 this(in Point position, in Vector size) { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
140 this(position.x, position.y, size.x, size.y); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
141 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
142 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
143 this(in Point corner1, in Point corner) { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
144 this(corner1.x, corner1.y, corner.x - corner1.x, corner.y - corner1.y); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
145 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
146 |
132 | 147 @property double x0() const { return _position.x; } |
148 @property double y0() const { return _position.y; } | |
149 @property double w() const { return _size.x; } | |
150 @property double h() const { return _size.y; } | |
151 @property double x1() const { return x0 + w; } | |
152 @property double y1() const { return y0 + h; } | |
70 | 153 |
154 alias position corner0; | |
132 | 155 @property Point position() const { return _position; } |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
156 |
132 | 157 @property Vector size() const { return _size; } |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
158 |
132 | 159 @property Point corner1() const { return _position + _size; } |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
160 |
132 | 161 @property bool valid() const { return _size.x > 0.0 && _size.y > 0.0; } |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
162 |
132 | 163 @property bool invalid() const { return !valid(); } |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
164 |
132 | 165 @property double area() const { return _size.x * _size.y; } |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
166 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
167 // Intersection |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
168 Rectangle opAnd(in Rectangle r) const { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
169 if (invalid() || r.invalid()) { |
100 | 170 return Rectangle(); |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
171 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
172 else { |
70 | 173 Point max = minExtents(corner1(), r.corner1()); |
174 Point min = maxExtents(corner0(), r.corner0()); | |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
175 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
176 if (max.x < min.x || max.y < min.y) { |
100 | 177 return Rectangle(); |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
178 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
179 else { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
180 return Rectangle(min, max); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
181 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
182 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
183 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
184 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
185 // Union |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
186 Rectangle opOr(in Rectangle r) const { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
187 if (invalid()) { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
188 return r; |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
189 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
190 else if (r.invalid()) { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
191 return this; |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
192 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
193 else { |
70 | 194 return Rectangle(minExtents(corner0(), r.corner0()), |
195 maxExtents(corner1(), r.corner1())); | |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
196 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
197 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
198 |
136 | 199 bool contains(in Rectangle r) const { |
200 if (r.valid) { | |
201 return x0 <= r.x0 && y0 <= r.y0 && x1 >= r.x1 && y1 >= r.y1; | |
202 } | |
203 else { | |
204 return valid; | |
205 } | |
206 } | |
207 | |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
208 // |
15 | 209 |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
210 // FIXME this method is all about pixels. Not sure it belongs in |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
211 // this file, let alone this class. |
48 | 212 void getQuantised(out int x, out int y, out int w, out int h) const { |
17 | 213 x = cast(int)floor(_position.x); |
214 y = cast(int)floor(_position.y); | |
215 w = cast(int)ceil(_position.x + _size.x) - x; | |
216 h = cast(int)ceil(_position.y + _size.y) - y; | |
217 } | |
218 | |
219 // | |
220 | |
132 | 221 @property Point centre() const { return _position + _size / 2.0; } |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
222 |
62 | 223 string toString() { |
4
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
224 return std.string.format("{%s, %s}", _position, _size); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
225 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
226 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
227 private { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
228 this(double x, double y, double w, double h) { |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
229 if (w < 0.0) { x += w; w = -w; } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
230 if (h < 0.0) { y += h; h = -h; } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
231 _position = Point(x, y); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
232 _size = Vector(w, h); |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
233 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
234 |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
235 Point _position; |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
236 Vector _size; |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
237 } |
58a8ad20b228
Ooops, this got left out of previous commit
David Bryant <daveb@acres.com.au>
parents:
diff
changeset
|
238 } |
25 | 239 |
79 | 240 Rectangle growCentre(in Rectangle r, in Vector amount) { |
241 return Rectangle(r.x0 - amount.x / 2, r.y0 - amount.y / 2, r.w + amount.x, r.h + amount.y); | |
242 } | |
243 | |
244 Rectangle growCentre(in Rectangle r, in double amount) { | |
245 return Rectangle(r.x0 - amount / 2, r.y0 - amount / 2, r.w + amount, r.h + amount); | |
246 } | |
247 | |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
248 // TODO review these functions. |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
249 // Want a clear and simple set. |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
250 |
79 | 251 /+ |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
252 Rectangle move(in Rectangle r, in Vector displacement) { |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
253 return Rectangle(r.position + displacement, r.size); |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
254 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
255 |
66 | 256 Rectangle reposition(in Rectangle r, in Point newPosition) { |
257 return Rectangle(newPosition, r.size); | |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
258 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
259 |
41 | 260 Rectangle resize(in Rectangle r, in Vector new_size) { |
261 return Rectangle(r.position, new_size); | |
262 } | |
263 | |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
264 // Operations about the bottom left corner |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
265 |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
266 Rectangle expand(in Rectangle r, in Vector expand_amount) { |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
267 return Rectangle(r.position, r.size + expand_amount); |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
268 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
269 |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
270 Rectangle shrink(in Rectangle r, in Vector shrink_amount) { |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
271 return Rectangle(r.position, r.size - shrink_amount); |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
272 } |
79 | 273 +/ |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
274 |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
275 // Operations about the centre |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
276 |
79 | 277 /+ |
78 | 278 Rectangle feather(in Rectangle r, double amount) { // feather isn't the right name |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
279 assert(amount >= 0.0); |
41 | 280 assert(!isnan(amount)); |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
281 return Rectangle(Point(r.position.x - amount, r.position.y - amount), |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
282 Vector(r.size.x + 2.0 * amount, r.size.y + 2.0 * amount)); |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
283 } |
79 | 284 +/ |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
285 |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
286 private { |
41 | 287 // This function computes the intersection of two lines. |
288 // The lines are defined by a start point and an end point, however they | |
289 // notionally extend infinitely in each direction. | |
290 // The out parameters specify the fraction along the line-segment at which | |
291 // intersection occurred. | |
292 // | |
293 // This is a commmon building block for computing intersection between lines, segments, | |
294 // rectangles, etc. | |
295 // | |
296 // The function returns false if the lines are parallel or nearly so. | |
297 // | |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
298 // Influenced by http://ozviz.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ |
48 | 299 bool computeIntersection(in Point pa1, in Point pa2, out double ua, |
66 | 300 in Point pb1, in Point pb2, out double ub) { |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
301 double den = (pb2.y - pb1.y) * (pa2.x - pa1.x) - (pb2.x - pb1.x) * (pa2.y - pa1.y); |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
302 |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
303 if (abs(den) < 1e-9) { // TODO consolidate constants used for numerical stability |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
304 // Lines are parallel or nearly so |
41 | 305 warning("Warning, parallel lines!"); |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
306 return false; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
307 } |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
308 else { |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
309 // It will be safe to divide by den |
66 | 310 double numA = (pb2.x - pb1.x) * (pa1.y - pb1.y) - (pb2.y - pb1.y) * (pa1.x - pb1.x); |
311 double numB = (pa2.x - pa1.x) * (pa1.y - pb1.y) - (pa2.y - pa1.y) * (pa1.x - pb1.x); | |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
312 |
66 | 313 ua = numA / den; |
314 ub = numB / den; | |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
315 |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
316 return true; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
317 } |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
318 } |
41 | 319 |
320 /+ | |
66 | 321 double compute_angle(in Point p1, in Point p2) { |
322 } | |
41 | 323 +/ |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
324 } |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
325 |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
326 // |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
327 // A line (notionally infinitely extending in both directions) in 2D space. |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
328 // Internally represented by: |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
329 // a point at an arbitrary location along the line |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
330 // a vector defining the gradient of the line |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
331 // |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
332 |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
333 struct Line { |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
334 this(in Point p, in Vector g) { |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
335 _point = p; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
336 _gradient = g; |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
337 // FIXME should we normalise (make unit length) the gradient? |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
338 assert(_gradient.length > 1e-6); // FIXME how to best deal with this |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
339 } |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
340 |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
341 this(in Point a, in Point b) { |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
342 _point = a; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
343 _gradient = b - a; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
344 assert(_gradient.length > 1e-6); // FIXME as above |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
345 } |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
346 |
132 | 347 @property Point point() const { return _point; } |
348 @property Vector gradient() const { return _gradient; } | |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
349 |
62 | 350 string toString() { |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
351 return std.string.format("{%s %s}", _point, _gradient); |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
352 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
353 |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
354 private { |
51 | 355 Point _point; // Arbitrary point along line |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
356 Vector _gradient; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
357 } |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
358 } |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
359 |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
360 // Calculate the point "p" where lines "a" and "b" intersect. |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
361 // Returns false if lines are parallel or too close for numerical stability |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
362 bool intersection(in Line a, in Line b, out Point p) { |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
363 Point pa = a.point; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
364 Vector va = a.gradient; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
365 double ua; |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
366 |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
367 Point pb = b.point; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
368 Vector vb = b.gradient; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
369 double ub; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
370 |
48 | 371 if (computeIntersection(pa, pa + va, ua, pb, pb + vb, ub)) { |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
372 // We could just have easily evaluated for line b... |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
373 p = pa + ua * va; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
374 // p = pb + ub * vb; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
375 return true; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
376 } |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
377 else { |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
378 return false; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
379 } |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
380 } |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
381 |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
382 // |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
383 // A line segment (has a beginning and an end) in 2D space. |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
384 // |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
385 |
25 | 386 struct Segment { |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
387 this(in Point a, in Point b) { |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
388 _begin = a; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
389 _end = b; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
390 } |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
391 |
132 | 392 @property Point begin() const { return _begin; } |
393 @property Point end() const { return _end; } | |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
394 |
62 | 395 string toString() { |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
396 return std.string.format("{%s %s}", _begin, _end); |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
397 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
398 |
25 | 399 private { |
400 Point _begin, _end; | |
401 } | |
402 } | |
403 | |
79 | 404 /* |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
405 Segment reverse(in Segment s) { |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
406 return Segment(s.end, s.begin); |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
407 } |
79 | 408 */ |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
409 |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
410 bool intersection(in Segment a, in Segment b, out Point p) { |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
411 Point pa1 = a.begin; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
412 Point pa2 = a.end; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
413 double ua; |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
414 |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
415 Point pb1 = b.begin; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
416 Point pb2 = b.end; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
417 double ub; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
418 |
48 | 419 if (computeIntersection(pa1, pa2, ua, pb1, pb2, ub)) { |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
420 if (ua >= 0.0 && ua <= 1.0 && // inside of segment a |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
421 ub >= 0.0 && ub <= 1.0) { // inside of segment b |
67 | 422 // We could just as easily evaluated for line b... |
33
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
423 p = pa1 + ua * (pa2 - pa1); |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
424 // p = pa2 + ub * (pb2 - pb1); |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
425 return true; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
426 } |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
427 else { |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
428 return false; |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
429 } |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
430 } |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
431 else { |
157b4ad5615d
Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents:
28
diff
changeset
|
432 return false; |
25 | 433 } |
434 } | |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
435 |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
436 bool intersection(in Segment a, in Line b, out Point p) { |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
437 Point pa1 = a.begin; |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
438 Point pa2 = a.end; |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
439 double ua; |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
440 |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
441 Point pb = b.point; |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
442 Vector vb = b.gradient; |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
443 double ub; |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
444 |
48 | 445 if (computeIntersection(pa1, pa2, ua, pb, pb + vb, ub)) { |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
446 if (ua >= 0.0 && ua <= 1.0) { // inside of segment |
67 | 447 // We could just as easily evaluated for line b... |
34
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
448 p = pa1 + ua * (pa2 - pa1); |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
449 // p = pb + ub * vb; |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
450 return true; |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
451 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
452 else { |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
453 return false; |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
454 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
455 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
456 else { |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
457 return false; |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
458 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
459 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
460 |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
461 bool intersection(in Line a, in Segment b, out Point p) { |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
462 // Equivalent to intersection of segment and line. Just reverse the args. |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
463 return intersection(b, a, p); |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
464 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
465 |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
466 /+ |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
467 bool intersection(in Line l, in Rectangle r, out Point p1, out Point p2) { |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
468 // TODO |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
469 return false; |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
470 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
471 |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
472 bool intersection(in Segment s, in Rectangle r, out Point p1, out Point p2) { |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
473 // TODO |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
474 return false; |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
475 } |
c2f11e1d7470
Geometry cleanup and checkpoint.
David Bryant <bagnose@gmail.com>
parents:
33
diff
changeset
|
476 +/ |