1 package org.catacomb.be;
2
3 import org.catacomb.report.E;
4
5
6 public final class Position implements XYLocation {
7
8 double x;
9 double y;
10
11 boolean valid;
12
13 public Position() {
14 this(999.9, 999.9);
15 valid = false;
16 }
17
18 public Position(XYLocation p) {
19 set(p.getX(), p.getY());
20 }
21
22
23 public Position(double px, double py) {
24 set(px, py);
25 }
26
27
28 public String toString() {
29 return "position(" + x + ", " + y + ")";
30 }
31
32
33 public void set(XYLocation p) {
34 set(p.getX(), p.getY());
35 }
36
37 public void add(Position p) {
38 reportInValid();
39 x += p.getX();
40 y += p.getY();
41 }
42
43 public void subtract(Position p) {
44 reportInValid();
45 x -= p.getX();
46 y -= p.getY();
47 }
48
49
50 public void absolutize(Position porig, double scale, Position prel) {
51
52
53 set(porig.getX() + scale * prel.getX(),
54 porig.getY() + scale * prel.getY());
55
56 }
57
58
59 public void relativize(Position porig, double scale, Position pabs) {
60
61 set((pabs.getX() - porig.getX()) / scale,
62 (pabs.getY() - porig.getY()) / scale);
63 }
64
65
66 private void reportInValid() {
67 if (valid) {
68
69 } else {
70 E.warning("using a default position? " + x + " " + y);
71 }
72 }
73
74
75 public void set(double px, double py) {
76 x = px;
77 y = py;
78 valid = true;
79 }
80
81
82 public double getX() {
83 reportInValid();
84 return x;
85 }
86
87
88 public double getY() {
89 reportInValid();
90 return y;
91 }
92
93
94
95 public static Position aXPlusBY(double a, Position v, double b, Position w) {
96 Position ret = new Position(a * v.getX() + b * w.getX(),
97 a * v.getY() + b * w.getY());
98 return ret;
99 }
100
101
102 public void shift(double dx, double dy) {
103 x += dx;
104 y += dy;
105 }
106
107 public void shift(Position spos) {
108 x += spos.getX();
109 y += spos.getY();
110 }
111
112
113 public boolean isValid() {
114 return valid;
115 }
116
117 public Position copy() {
118 return new Position(this);
119 }
120
121 public double distanceFrom(Position p) {
122 double dx = p.getX() - x;
123 double dy = p.getY() - y;
124 return Math.sqrt(dx*dx + dy*dy);
125 }
126
127 public double distanceFromOrigin() {
128 return Math.sqrt(x*x + y*y);
129 }
130
131
132
133 public Position getRelativeToBoxCenter(double[] xyxy) {
134 double cx = (xyxy[2] + xyxy[0]) / 2;
135 double dx = (xyxy[2] - xyxy[0]) / 2;
136 double cy = (xyxy[3] + xyxy[1]) / 2;
137 double dy = (xyxy[3] - xyxy[1]) / 2;
138
139 return new Position((x - cx) / dx, (y - cy) / dy);
140 }
141
142 public void setX(double d) {
143 x = d;
144 }
145
146 public void setY(double d) {
147 y = d;
148 }
149
150 public static Position midpoint(Position pa, Position pb) {
151 return new Position(0.5 * (pa.x + pb.x), 0.5*(pa.y + pb.y));
152 }
153
154
155 public void rotateBy(double rad) {
156 double c = Math.cos(rad);
157 double s = Math.sin(rad);
158 rotateCosSin(c, s);
159 }
160
161 private void rotateCosSin(double c, double s) {
162 double xr = c * x - s * y;
163 double yr = s * x + c * y;
164 x = xr;
165 y = yr;
166 }
167
168
169 public void rotateTo(Direction dir) {
170 double c = dir.getCosine();
171 double s = dir.getSine();
172 rotateCosSin(c, s);
173 }
174
175
176 public void rotateAbout(Position pcen, double rad) {
177 double c = Math.cos(rad);
178 double s = Math.sin(rad);
179 double cx = pcen.getX();
180 double cy = pcen.getY();
181 double dx = x - cx;
182 double dy = y - cy;
183 x = cx + c * dx - s * dy;
184 y = cy + s * dx + c * dy;
185 }
186
187
188 }