Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(234)

Side by Side Diff: sdk/lib/math/rectangle.dart

Issue 135273009: Make Rectangle and MutableRectangle constructors handle negative lengths. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Update tests. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sdk/lib/html/dartium/html_dartium.dart ('k') | tests/lib/math/rectangle_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 part of dart.math; 4 part of dart.math;
5 5
6 /** 6 /**
7 * A base class for representing two-dimensional axis-aligned rectangles. 7 * A base class for representing two-dimensional axis-aligned rectangles.
8 * 8 *
9 * This rectangle uses a left-handed Cartesian coordinate system, with x 9 * This rectangle uses a left-handed Cartesian coordinate system, with x
10 * directed to the right and y directed down, as per the convention in 2D 10 * directed to the right and y directed down, as per the convention in 2D
11 * computer graphics. 11 * computer graphics.
12 * 12 *
13 * See also: 13 * See also:
14 * [W3C Coordinate Systems Specification](http://www.w3.org/TR/SVG/coords.htm l#InitialCoordinateSystem). 14 * [W3C Coordinate Systems Specification](http://www.w3.org/TR/SVG/coords.htm l#InitialCoordinateSystem).
15 *
16 * The rectangle is the set of points with representable coordinates greater
17 * than or equal to left/top, and with distance to left/top no greater than
18 * width/height (to the limit of the precission of the coordinates).
15 */ 19 */
16 abstract class _RectangleBase<T extends num> { 20 abstract class _RectangleBase<T extends num> {
17 const _RectangleBase(); 21 const _RectangleBase();
18 22
19 /** The x-coordinate of the left edge. */ 23 /** The x-coordinate of the left edge. */
20 T get left; 24 T get left;
21 /** The y-coordinate of the top edge. */ 25 /** The y-coordinate of the top edge. */
22 T get top; 26 T get top;
23 /** The `width` of the rectangle. */ 27 /** The width of the rectangle. */
24 T get width; 28 T get width;
25 /** The `height` of the rectangle. */ 29 /** The height of the rectangle. */
26 T get height; 30 T get height;
27 31
28 /** The x-coordinate of the right edge. */ 32 /** The x-coordinate of the right edge. */
29 T get right => left + width; 33 T get right => left + width;
30 /** The y-coordinate of the bottom edge. */ 34 /** The y-coordinate of the bottom edge. */
31 T get bottom => top + height; 35 T get bottom => top + height;
32 36
33 String toString() { 37 String toString() {
34 return 'Rectangle ($left, $top) $width x $height'; 38 return 'Rectangle ($left, $top) $width x $height';
35 } 39 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 /** 127 /**
124 * A class for representing two-dimensional rectangles whose properties are 128 * A class for representing two-dimensional rectangles whose properties are
125 * immutable. 129 * immutable.
126 */ 130 */
127 class Rectangle<T extends num> extends _RectangleBase<T> { 131 class Rectangle<T extends num> extends _RectangleBase<T> {
128 final T left; 132 final T left;
129 final T top; 133 final T top;
130 final T width; 134 final T width;
131 final T height; 135 final T height;
132 136
133 const Rectangle(this.left, this.top, this.width, this.height); 137 /**
138 * Create a rectangle spanned by `(left, top)` and `(left+width, top+height)`.
139 *
140 * The rectangle contains the points
141 * with x-coordinate between `left` and `left + width`, and
142 * with y-coordiante between `top` and `top + height`, both inclusive.
143 *
144 * The `width` and `height` should be non-negative.
145 * If `width` or `height` are negative, they are clamped to zero.
146 *
147 * If `width` and `height` are zero, the "rectangle" comprises only the single
148 * point `(left, top)`.
149 */
150 const Rectangle(this.left, this.top, T width, T height)
151 : this.width = (width >= 0) ? width : -width * 0, // Inline _clampToZero.
152 this.height = (height >= 0) ? height : -height * 0;
134 153
154 /*
155 * Create a rectangle spanned by the points [a] and [b];
156 *
157 * The rectangle contains the points
158 * with x-coordinate between `a.x` and `b.x`, and
159 * with y-coordiante between `a.y` and `b.y`, both inclusive.
160 *
161 * If the distance between `a.x` and `b.x` is not representable
162 * (which can happen if one or both is a double),
163 * the actual right edge might be slightly off from `max(a.x, b.x)`.
164 * Similar for the y-coordinates and the bottom edge.
165 */
135 factory Rectangle.fromPoints(Point<T> a, Point<T> b) { 166 factory Rectangle.fromPoints(Point<T> a, Point<T> b) {
136 T left = min(a.x, b.x); 167 T left = min(a.x, b.x);
137 T width = max(a.x, b.x) - left; 168 T width = max(a.x, b.x) - left;
138 T top = min(a.y, b.y); 169 T top = min(a.y, b.y);
139 T height = max(a.y, b.y) - top; 170 T height = max(a.y, b.y) - top;
140 return new Rectangle<T>(left, top, width, height); 171 return new Rectangle<T>(left, top, width, height);
141 } 172 }
142 } 173 }
143 174
144 /** 175 /**
145 * A class for representing two-dimensional axis-aligned rectangles with mutable 176 * A class for representing two-dimensional axis-aligned rectangles with mutable
146 * properties. 177 * properties.
147 */ 178 */
148 class MutableRectangle<T extends num> extends _RectangleBase<T> 179 class MutableRectangle<T extends num> extends _RectangleBase<T>
149 implements Rectangle<T> { 180 implements Rectangle<T> {
181
182 /**
183 * The x-coordinate of the left edge.
184 *
185 * Setting the value will move the rectangle without changing its width.
186 */
150 T left; 187 T left;
188 /**
189 * The y-coordinate of the left edge.
190 *
191 * Setting the value will move the rectangle without changing its height.
192 */
151 T top; 193 T top;
152 T width; 194 T _width;
153 T height; 195 T _height;
154 196
155 MutableRectangle(this.left, this.top, this.width, this.height); 197 /**
198 * Create a mutable rectangle spanned by `(left, top)` and
199 * `(left+width, top+height)`.
200 *
201 * The rectangle contains the points
202 * with x-coordinate between `left` and `left + width`, and
203 * with y-coordiante between `top` and `top + height`, both inclusive.
204 *
205 * The `width` and `height` should be non-negative.
206 * If `width` or `height` are negative, they are clamped to zero.
207 *
208 * If `width` and `height` are zero, the "rectangle" comprises only the single
209 * point `(left, top)`.
210 */
211 MutableRectangle(this.left, this.top, T width, T height)
212 : this._width = (width >= 0) ? width : _clampToZero(width),
213 this._height = (height >= 0) ? height : _clampToZero(height);
156 214
215 /*
216 * Create a mutable rectangle spanned by the points [a] and [b];
217 *
218 * The rectangle contains the points
219 * with x-coordinate between `a.x` and `b.x`, and
220 * with y-coordiante between `a.y` and `b.y`, both inclusive.
221 *
222 * If the distance between `a.x` and `b.x` is not representable
223 * (which can happen if one or both is a double),
224 * the actual right edge might be slightly off from `max(a.x, b.x)`.
225 * Similar for the y-coordinates and the bottom edge.
226 */
157 factory MutableRectangle.fromPoints(Point<T> a, Point<T> b) { 227 factory MutableRectangle.fromPoints(Point<T> a, Point<T> b) {
158 T left = min(a.x, b.x); 228 T left = min(a.x, b.x);
159 T width = max(a.x, b.x) - left; 229 T width = max(a.x, b.x) - left;
160 T top = min(a.y, b.y); 230 T top = min(a.y, b.y);
161 T height = max(a.y, b.y) - top; 231 T height = max(a.y, b.y) - top;
162 return new MutableRectangle<T>(left, top, width, height); 232 return new MutableRectangle<T>(left, top, width, height);
163 } 233 }
234
235 T get width => _width;
236
237 /**
238 * Sets the width of the rectangle.
239 *
240 * The width must be non-negative.
241 * If a negative width is supplied, it is clamped to zero.
242 *
243 * Setting the value will change the right edge of the rectangle,
244 * but will not change [left].
245 */
246 void set width(T width) {
247 if (width < 0) width = _clampToZero(width);
248 _width = width;
249 }
250
251 T get height => _height;
252
253 /**
254 * Sets the height of the rectangle.
255 *
256 * The height must be non-negative.
257 * If a negative height is supplied, it is clamped to zero.
258 *
259 * Setting the value will change the bottom edge of the rectangle,
260 * but will not change [top].
261 */
262 void set height(T height) {
263 if (height < 0) height = _clampToZero(height);
264 _height = height;
265 }
164 } 266 }
267
268 /**
269 * Converts a negative [int] or [double] to a zero-value of the same type.
270 *
271 * Returns `0` if value is int, `0.0` if value is double.
272 */
273 num _clampToZero(num value) {
274 assert(value < 0);
275 return -value * 0;
276 }
OLDNEW
« no previous file with comments | « sdk/lib/html/dartium/html_dartium.dart ('k') | tests/lib/math/rectangle_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698