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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
31d10176415d Checkpoint
daveb
parents: 66
diff changeset
6 import doodle.core.misc;
41
daveb
parents: 40
diff changeset
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
6c3993f4c3eb Checkpoint
daveb
parents: 51
diff changeset
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
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
48 @property double x() const { return _x; }
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
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
a274d16ab6ce struct initialisers
David Bryant <bagnose@gmail.com>
parents: 79
diff changeset
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
1b4c9ba58673 Stylistic overhaul.
daveb
parents: 41
diff changeset
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
1b4c9ba58673 Stylistic overhaul.
daveb
parents: 41
diff changeset
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
daveb
parents: 40
diff changeset
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
daveb
parents: 40
diff changeset
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
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
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
6c3993f4c3eb Checkpoint
daveb
parents: 51
diff changeset
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
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
104 @property double x() const { return _x; }
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
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
a274d16ab6ce struct initialisers
David Bryant <bagnose@gmail.com>
parents: 79
diff changeset
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
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
112 /*
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
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
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
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
43cc2135ced0 Some code cleanups
"David Bryant <bagnose@gmail.com>"
parents: 62
diff changeset
135 static Rectangle from_arbitrary_corners(in Point corner1, in Point corner) {
43cc2135ced0 Some code cleanups
"David Bryant <bagnose@gmail.com>"
parents: 62
diff changeset
136 }
43cc2135ced0 Some code cleanups
"David Bryant <bagnose@gmail.com>"
parents: 62
diff changeset
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
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
147 @property double x0() const { return _position.x; }
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
148 @property double y0() const { return _position.y; }
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
149 @property double w() const { return _size.x; }
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
150 @property double h() const { return _size.y; }
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
151 @property double x1() const { return x0 + w; }
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
152 @property double y1() const { return y0 + h; }
70
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 67
diff changeset
153
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 67
diff changeset
154 alias position corner0;
132
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
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
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
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
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
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
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
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
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
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
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
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
a274d16ab6ce struct initialisers
David Bryant <bagnose@gmail.com>
parents: 79
diff changeset
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
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 67
diff changeset
173 Point max = minExtents(corner1(), r.corner1());
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 67
diff changeset
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
a274d16ab6ce struct initialisers
David Bryant <bagnose@gmail.com>
parents: 79
diff changeset
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
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 67
diff changeset
194 return Rectangle(minExtents(corner0(), r.corner0()),
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 67
diff changeset
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
752676232e4b Port to GtkD-2.0 (gtk+3)
David Bryant <bagnose@gmail.com>
parents: 132
diff changeset
199 bool contains(in Rectangle r) const {
752676232e4b Port to GtkD-2.0 (gtk+3)
David Bryant <bagnose@gmail.com>
parents: 132
diff changeset
200 if (r.valid) {
752676232e4b Port to GtkD-2.0 (gtk+3)
David Bryant <bagnose@gmail.com>
parents: 132
diff changeset
201 return x0 <= r.x0 && y0 <= r.y0 && x1 >= r.x1 && y1 >= r.y1;
752676232e4b Port to GtkD-2.0 (gtk+3)
David Bryant <bagnose@gmail.com>
parents: 132
diff changeset
202 }
752676232e4b Port to GtkD-2.0 (gtk+3)
David Bryant <bagnose@gmail.com>
parents: 132
diff changeset
203 else {
752676232e4b Port to GtkD-2.0 (gtk+3)
David Bryant <bagnose@gmail.com>
parents: 132
diff changeset
204 return valid;
752676232e4b Port to GtkD-2.0 (gtk+3)
David Bryant <bagnose@gmail.com>
parents: 132
diff changeset
205 }
752676232e4b Port to GtkD-2.0 (gtk+3)
David Bryant <bagnose@gmail.com>
parents: 132
diff changeset
206 }
752676232e4b Port to GtkD-2.0 (gtk+3)
David Bryant <bagnose@gmail.com>
parents: 132
diff changeset
207
33
157b4ad5615d Added intersection code for lines and segments.
David Bryant <bagnose@gmail.com>
parents: 28
diff changeset
208 //
15
2f79aab4d385 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 13
diff changeset
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
1b4c9ba58673 Stylistic overhaul.
daveb
parents: 41
diff changeset
212 void getQuantised(out int x, out int y, out int w, out int h) const {
17
c643c04e3f5e Checkpoint
David Bryant <daveb@acres.com.au>
parents: 16
diff changeset
213 x = cast(int)floor(_position.x);
c643c04e3f5e Checkpoint
David Bryant <daveb@acres.com.au>
parents: 16
diff changeset
214 y = cast(int)floor(_position.y);
c643c04e3f5e Checkpoint
David Bryant <daveb@acres.com.au>
parents: 16
diff changeset
215 w = cast(int)ceil(_position.x + _size.x) - x;
c643c04e3f5e Checkpoint
David Bryant <daveb@acres.com.au>
parents: 16
diff changeset
216 h = cast(int)ceil(_position.y + _size.y) - y;
c643c04e3f5e Checkpoint
David Bryant <daveb@acres.com.au>
parents: 16
diff changeset
217 }
c643c04e3f5e Checkpoint
David Bryant <daveb@acres.com.au>
parents: 16
diff changeset
218
c643c04e3f5e Checkpoint
David Bryant <daveb@acres.com.au>
parents: 16
diff changeset
219 //
c643c04e3f5e Checkpoint
David Bryant <daveb@acres.com.au>
parents: 16
diff changeset
220
132
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
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
6c3993f4c3eb Checkpoint
daveb
parents: 51
diff changeset
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
8f58a8f88735 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 19
diff changeset
239
79
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
240 Rectangle growCentre(in Rectangle r, in Vector amount) {
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
241 return Rectangle(r.x0 - amount.x / 2, r.y0 - amount.y / 2, r.w + amount.x, r.h + amount.y);
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
242 }
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
243
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
244 Rectangle growCentre(in Rectangle r, in double amount) {
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
245 return Rectangle(r.x0 - amount / 2, r.y0 - amount / 2, r.w + amount, r.h + amount);
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
246 }
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
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
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
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
43cc2135ced0 Some code cleanups
"David Bryant <bagnose@gmail.com>"
parents: 62
diff changeset
256 Rectangle reposition(in Rectangle r, in Point newPosition) {
43cc2135ced0 Some code cleanups
"David Bryant <bagnose@gmail.com>"
parents: 62
diff changeset
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
daveb
parents: 40
diff changeset
260 Rectangle resize(in Rectangle r, in Vector new_size) {
daveb
parents: 40
diff changeset
261 return Rectangle(r.position, new_size);
daveb
parents: 40
diff changeset
262 }
daveb
parents: 40
diff changeset
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
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
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
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
277 /+
78
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
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
daveb
parents: 40
diff changeset
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
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
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
daveb
parents: 40
diff changeset
287 // This function computes the intersection of two lines.
daveb
parents: 40
diff changeset
288 // The lines are defined by a start point and an end point, however they
daveb
parents: 40
diff changeset
289 // notionally extend infinitely in each direction.
daveb
parents: 40
diff changeset
290 // The out parameters specify the fraction along the line-segment at which
daveb
parents: 40
diff changeset
291 // intersection occurred.
daveb
parents: 40
diff changeset
292 //
daveb
parents: 40
diff changeset
293 // This is a commmon building block for computing intersection between lines, segments,
daveb
parents: 40
diff changeset
294 // rectangles, etc.
daveb
parents: 40
diff changeset
295 //
daveb
parents: 40
diff changeset
296 // The function returns false if the lines are parallel or nearly so.
daveb
parents: 40
diff changeset
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
1b4c9ba58673 Stylistic overhaul.
daveb
parents: 41
diff changeset
299 bool computeIntersection(in Point pa1, in Point pa2, out double ua,
66
43cc2135ced0 Some code cleanups
"David Bryant <bagnose@gmail.com>"
parents: 62
diff changeset
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
daveb
parents: 40
diff changeset
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
43cc2135ced0 Some code cleanups
"David Bryant <bagnose@gmail.com>"
parents: 62
diff changeset
310 double numA = (pb2.x - pb1.x) * (pa1.y - pb1.y) - (pb2.y - pb1.y) * (pa1.x - pb1.x);
43cc2135ced0 Some code cleanups
"David Bryant <bagnose@gmail.com>"
parents: 62
diff changeset
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
43cc2135ced0 Some code cleanups
"David Bryant <bagnose@gmail.com>"
parents: 62
diff changeset
313 ua = numA / den;
43cc2135ced0 Some code cleanups
"David Bryant <bagnose@gmail.com>"
parents: 62
diff changeset
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
daveb
parents: 40
diff changeset
319
daveb
parents: 40
diff changeset
320 /+
66
43cc2135ced0 Some code cleanups
"David Bryant <bagnose@gmail.com>"
parents: 62
diff changeset
321 double compute_angle(in Point p1, in Point p2) {
43cc2135ced0 Some code cleanups
"David Bryant <bagnose@gmail.com>"
parents: 62
diff changeset
322 }
41
daveb
parents: 40
diff changeset
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
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
347 @property Point point() const { return _point; }
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
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
6c3993f4c3eb Checkpoint
daveb
parents: 51
diff changeset
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
0eaf39fda206 First cut at palette class
daveb
parents: 48
diff changeset
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
1b4c9ba58673 Stylistic overhaul.
daveb
parents: 41
diff changeset
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
8f58a8f88735 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 19
diff changeset
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
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
392 @property Point begin() const { return _begin; }
bc5baa585b32 Updated to dmd 2.060
David Bryant <bagnose@gmail.com>
parents: 100
diff changeset
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
6c3993f4c3eb Checkpoint
daveb
parents: 51
diff changeset
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
8f58a8f88735 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 19
diff changeset
399 private {
8f58a8f88735 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 19
diff changeset
400 Point _begin, _end;
8f58a8f88735 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 19
diff changeset
401 }
8f58a8f88735 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 19
diff changeset
402 }
8f58a8f88735 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 19
diff changeset
403
79
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
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
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
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
1b4c9ba58673 Stylistic overhaul.
daveb
parents: 41
diff changeset
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
31d10176415d Checkpoint
daveb
parents: 66
diff changeset
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
8f58a8f88735 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 19
diff changeset
433 }
8f58a8f88735 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 19
diff changeset
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
1b4c9ba58673 Stylistic overhaul.
daveb
parents: 41
diff changeset
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
31d10176415d Checkpoint
daveb
parents: 66
diff changeset
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 +/