| OLD | NEW |
| 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 Loading... |
| 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 } |
| OLD | NEW |