comparison dwtx/draw2d/geometry/PrecisionRectangle.d @ 98:95307ad235d9

Added Draw2d code, still work in progress
author Frank Benoit <benoit@tionex.de>
date Sun, 03 Aug 2008 00:52:14 +0200
parents
children
comparison
equal deleted inserted replaced
96:b492ba44e44d 98:95307ad235d9
1 /*******************************************************************************
2 * Copyright (c) 2003, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13 module dwtx.draw2d.geometry.PrecisionRectangle;
14
15 import dwt.dwthelper.utils;
16 import dwtx.draw2d.geometry.Rectangle;
17 import dwtx.draw2d.geometry.Insets;
18 import dwtx.draw2d.geometry.Point;
19 import dwtx.draw2d.geometry.Dimension;
20 import dwtx.draw2d.geometry.PrecisionPoint;
21
22 /**
23 * A Rectangle implementation using floating point values which are truncated into the inherited
24 * integer fields. The use of floating point prevents rounding errors from accumulating.
25 * @author hudsonr
26 * Created on Apr 9, 2003
27 */
28 public final class PrecisionRectangle : Rectangle {
29
30 /** Double value for height */
31 public double preciseHeight_;
32
33 /** Double value for width */
34 public double preciseWidth_;
35
36 /** Double value for X */
37 public double preciseX_;
38
39 /** Double value for Y */
40 public double preciseY_;
41
42 /**
43 * Constructs a new PrecisionRectangle with all values 0.
44 */
45 public this() { }
46
47 /**
48 * Constructs a new PrecisionRectangle from the given integer Rectangle.
49 * @param rect the base rectangle
50 */
51 public this(Rectangle rect) {
52 preciseX_ = rect.preciseX();
53 preciseY_ = rect.preciseY();
54 preciseWidth_ = rect.preciseWidth();
55 preciseHeight_ = rect.preciseHeight();
56 updateInts();
57 }
58
59 /**
60 * @see dwtx.draw2d.geometry.Rectangle#getCopy()
61 */
62 public Rectangle getCopy() {
63 return getPreciseCopy();
64 }
65
66 /**
67 * Returns a precise copy of this.
68 * @return a precise copy
69 */
70 public PrecisionRectangle getPreciseCopy() {
71 PrecisionRectangle result = new PrecisionRectangle();
72 result.preciseX_ = preciseX_;
73 result.preciseY_ = preciseY_;
74 result.preciseWidth_ = preciseWidth_;
75 result.preciseHeight_ = preciseHeight_;
76 result.updateInts();
77 return result;
78 }
79
80 /**
81 * @see dwtx.draw2d.geometry.Rectangle#crop(dwtx.draw2d.geometry.Insets)
82 */
83 public Rectangle crop(Insets insets) {
84 if (insets is null)
85 return this;
86 setX(preciseX_ + insets.left);
87 setY(preciseY_ + insets.top);
88 setWidth(preciseWidth_ - (insets.getWidth()));
89 setHeight(preciseHeight_ - (insets.getHeight()));
90
91 return this;
92 }
93
94 /**
95 * @see Rectangle#equals(Object)
96 */
97 public override int opEquals(Object o) {
98 if ( auto pr = cast(PrecisionRectangle)o ) {
99 return super.opEquals(o)
100 && Math.abs(pr.preciseX_ - preciseX_) < 0.000000001
101 && Math.abs(pr.preciseY_ - preciseY_) < 0.000000001
102 && Math.abs(pr.preciseWidth_ - preciseWidth_) < 0.000000001
103 && Math.abs(pr.preciseHeight_ - preciseHeight_) < 0.00000001;
104 }
105
106 return super.opEquals(o);
107 }
108
109 /**
110 * @see dwtx.draw2d.geometry.Rectangle#performScale(double)
111 */
112 public void performScale(double factor) {
113 preciseX_ *= factor;
114 preciseY_ *= factor;
115 preciseWidth_ *= factor;
116 preciseHeight_ *= factor;
117 updateInts();
118 }
119
120 /**
121 * @see dwtx.draw2d.geometry.Rectangle#performTranslate(int, int)
122 */
123 public void performTranslate(int dx, int dy) {
124 preciseX_ += dx;
125 preciseY_ += dy;
126 x += dx;
127 y += dy;
128 }
129
130 /**
131 * Returns the bottom coordinte in double precision.
132 * @return the precise bottom
133 */
134 public double preciseBottom() {
135 return preciseHeight_ + preciseY_;
136 }
137
138 /**
139 * Returns the right side in double precision.
140 * @return the precise right
141 */
142 public double preciseRight() {
143 return preciseWidth_ + preciseX_;
144 }
145
146
147 /**
148 * @see dwtx.draw2d.geometry.Rectangle#resize(dwtx.draw2d.geometry.Dimension)
149 */
150 public Rectangle resize(Dimension sizeDelta) {
151 preciseWidth_ += sizeDelta.preciseWidth();
152 preciseHeight_ += sizeDelta.preciseHeight();
153 updateInts();
154 return this;
155 }
156
157 /**
158 * Sets the height.
159 * @param value the new height
160 */
161 public void setHeight(double value) {
162 preciseHeight_ = value;
163 height = cast(int)Math.floor(preciseHeight_ + 0.000000001);
164 }
165
166 /**
167 * Sets the width.
168 * @param value the new width
169 */
170 public void setWidth(double value) {
171 preciseWidth_ = value;
172 width = cast(int)Math.floor(preciseWidth_ + 0.000000001);
173 }
174
175 /**
176 * Sets the x value.
177 * @param value the new x value
178 */
179 public void setX(double value) {
180 preciseX_ = value;
181 x = cast(int)Math.floor(preciseX_ + 0.000000001);
182 }
183
184 /**
185 * Sets the y value.
186 * @param value the new y value
187 */
188 public void setY(double value) {
189 preciseY_ = value;
190 y = cast(int)Math.floor(preciseY_ + 0.000000001);
191 }
192
193 /**
194 * @see dwtx.draw2d.geometry.Rectangle#translate(dwtx.draw2d.geometry.Point)
195 */
196 public Rectangle translate(Point p) {
197 preciseX_ += p.preciseX();
198 preciseY_ += p.preciseY();
199 updateInts();
200 return this;
201 }
202
203 /**
204 * Unions the given PrecisionRectangle with this rectangle and returns <code>this</code>
205 * for convenience.
206 * @since 3.0
207 * @param other the rectangle being unioned
208 * @return <code>this</code> for convenience
209 * @deprecated
210 * Use {@link #union(Rectangle)} instead
211 */
212 public PrecisionRectangle union_(PrecisionRectangle other) {
213 double newright = Math.max(preciseRight(), other.preciseRight());
214 double newbottom = Math.max(preciseBottom(), other.preciseBottom());
215 preciseX_ = Math.min(preciseX_, other.preciseX_);
216 preciseY_ = Math.min(preciseY_, other.preciseY_);
217 preciseWidth_ = newright - preciseX_;
218 preciseHeight_ = newbottom - preciseY_;
219 updateInts();
220
221 return this;
222 }
223
224 /**
225 * @see dwtx.draw2d.geometry.Rectangle#union(dwtx.draw2d.geometry.Rectangle)
226 */
227 public Rectangle union_(Rectangle other) {
228 double newright = Math.max(preciseRight(), other.preciseX() + other.preciseWidth());
229 double newbottom = Math.max(preciseBottom(), other.preciseY() + other.preciseHeight());
230 preciseX_ = Math.min(preciseX_, other.preciseX());
231 preciseY_ = Math.min(preciseY_, other.preciseY());
232 preciseWidth_ = newright - preciseX_;
233 preciseHeight_ = newbottom - preciseY_;
234 updateInts();
235
236 return this;
237 }
238
239 /**
240 * Updates the integer values based on the current precise values. The integer values ar
241 * the floor of the double values. This is called automatically when calling api which is
242 * overridden in this class.
243 * @since 3.0
244 */
245 public void updateInts() {
246 x = cast(int)Math.floor(preciseX_ + 0.000000001);
247 y = cast(int)Math.floor(preciseY_ + 0.000000001);
248 width = cast(int)Math.floor(preciseWidth_ + preciseX_ + 0.000000001) - x;
249 height = cast(int)Math.floor(preciseHeight_ + preciseY_ + 0.000000001) - y;
250 }
251
252 /**
253 * @see dwtx.draw2d.geometry.Rectangle#union(dwtx.draw2d.geometry.Point)
254 */
255 public void union_(Point p) {
256 if (p.preciseX() < preciseX_) {
257 preciseWidth_ += (preciseX_ - p.preciseX());
258 preciseX_ = p.preciseX();
259 } else {
260 double right = preciseX_ + preciseWidth_;
261 if (p.preciseX() > right) {
262 preciseWidth_ = p.preciseX() - preciseX_;
263 }
264 }
265 if (p.preciseY() < preciseY_) {
266 preciseHeight_ += (preciseY - p.preciseY());
267 preciseY_ = p.preciseY();
268 } else {
269 double bottom = preciseY_ + preciseHeight_;
270 if (p.preciseY() > bottom) {
271 preciseHeight_ = p.preciseY() - preciseY_;
272 }
273 }
274 updateInts();
275 }
276
277 /**
278 * @see dwtx.draw2d.geometry.Rectangle#transpose()
279 */
280 public Rectangle transpose() {
281 double temp = preciseX_;
282 preciseX_ = preciseY_;
283 preciseY_ = temp;
284 temp = preciseWidth_;
285 preciseWidth_ = preciseHeight_;
286 preciseHeight_ = temp;
287 super.transpose();
288 return this;
289 }
290
291 /**
292 * @see dwtx.draw2d.geometry.Rectangle#setLocation(dwtx.draw2d.geometry.Point)
293 */
294 public Rectangle setLocation(Point loc) {
295 preciseX_ = loc.preciseX();
296 preciseY_ = loc.preciseY();
297 updateInts();
298 return this;
299 }
300
301 /**
302 * Returns the precise geometric centre of the rectangle
303 *
304 * @return <code>PrecisionPoint</code> geometric center of the rectangle
305 * @since 3.4
306 */
307 public Point getCenter() {
308 return new PrecisionPoint(preciseX_ + preciseWidth_ / 2.0, preciseY_ + preciseHeight_ / 2.0);
309 }
310
311 /**
312 * Shrinks the sides of this Rectangle by the horizontal and vertical values
313 * provided as input, and returns this Rectangle for convenience. The center of
314 * this Rectangle is kept constant.
315 *
316 * @param h Horizontal reduction amount
317 * @param v Vertical reduction amount
318 * @return <code>this</code> for convenience
319 * @since 3.4
320 */
321 public Rectangle shrink(double h, double v) {
322 preciseX_ += h;
323 preciseWidth_ -= (h + h);
324 preciseY_ += v;
325 preciseHeight_ -= (v + v);
326 updateInts();
327 return this;
328 }
329
330 /**
331 * Expands the horizontal and vertical sides of this Rectangle with the values
332 * provided as input, and returns this for convenience. The location of its
333 * center is kept constant.
334 *
335 * @param h Horizontal increment
336 * @param v Vertical increment
337 * @return <code>this</code> for convenience
338 * @since 3.4
339 */
340 public Rectangle expand(double h, double v) {
341 return shrink(-h, -v);
342 }
343
344 /**
345 * @see dwtx.draw2d.geometry.Rectangle#shrink(int, int)
346 */
347 public Rectangle shrink(int h, int v) {
348 return shrink(cast(double)h, cast(double)v);
349 }
350
351 /**
352 * @see dwtx.draw2d.geometry.Rectangle#contains(dwtx.draw2d.geometry.Point)
353 */
354 public bool contains(Point p) {
355 return preciseX_ <= p.preciseX() && p.preciseX() <= preciseX_ + preciseWidth_
356 && preciseY_ <= p.preciseY() && p.preciseY() <= preciseY_ + preciseHeight_;
357 }
358
359 /**
360 * @see dwtx.draw2d.geometry.Rectangle#preciseX()
361 */
362 public double preciseX() {
363 return preciseX_;
364 }
365
366 /**
367 * @see dwtx.draw2d.geometry.Rectangle#preciseY()
368 */
369 public double preciseY() {
370 return preciseY_;
371 }
372
373 /**
374 * @see dwtx.draw2d.geometry.Rectangle#preciseWidth()
375 */
376 public double preciseWidth() {
377 return preciseWidth_;
378 }
379
380 /**
381 * @see dwtx.draw2d.geometry.Rectangle#preciseHeight()
382 */
383 public double preciseHeight() {
384 return preciseHeight_;
385 }
386
387 /**
388 * @see dwtx.draw2d.geometry.Rectangle#setSize(dwtx.draw2d.geometry.Dimension)
389 */
390 public Rectangle setSize(Dimension d) {
391 preciseWidth_ = d.preciseWidth();
392 preciseHeight_ = d.preciseHeight();
393 return super.setSize(d);
394 }
395
396 }