Mercurial > projects > doodle
view tk/geometry2.d @ 2:d6f44347373d
* Switched over to geometry done with structs instead of classes.
* Removed direct access to gtk structs
* Refactoring
author | David Bryant <daveb@acres.com.au> |
---|---|
date | Fri, 10 Jul 2009 15:15:27 +0930 |
parents | c18e3f93d114 |
children |
line wrap: on
line source
module tk.geometry2; private import std.stdio; private import std.math; private import tk.misc; struct Point2 { static immutable Point2 DEFAULT; static this() { DEFAULT = Point2(0.0, 0.0); } this(in double x, in double y) { _x = x; _y = y; } Point2 opAdd(in Vector2 v) const { return Point2(_x + v._x, _y + v._y); } Point2 opSub(in Vector2 v) const { return Point2(_x - v._x, _y - v._y); } Vector2 opSub(in Point2 p) const { return Vector2(_x - p._x, _y - p._y); } string toString() /* const */ { return std.string.format("(%f, %f)", _x, _y); } double x() const { return _x; } double y() const { return _y; } private { double _x, _y; } } Point2 min_extents(in Point2 a, in Point2 b) { return Point2(min(a.x, b.x), min(a.y, b.y)); } Point2 max_extents(in Point2 a, in Point2 b) { return Point2(max(a.x, b.x), max(a.y, b.y)); } struct Vector2 { static Vector2 DEFAULT; static this() { DEFAULT = Vector2(0.0, 0.0); } this(in double x, in double y) { _x = x; _y = y; } Vector2 opAdd(in Vector2 v) const { return Vector2(_x + v._x, _y + v._y); } Vector2 opSub(in Vector2 v) const { return Vector2(_x - v._x, _y - v._y); } Vector2 opNeg() const { return Vector2(-_x, -_y); } Vector2 opMul_r(in double d) const { return Vector2(d * _x, d * _y); } Vector2 opDiv(in double d) const { return Vector2(_x / d, _y / d); } double length() const { return sqrt(_x * _x + _y * _y); } string toString() /* const */ { return std.string.format("[%f, %f]", _x, _y); } double x() const { return _x; } double y() const { return _y; } private { double _x, _y; } } struct Rectangle2 { static Rectangle2 DEFAULT; static this() { DEFAULT = Rectangle2(Point2.DEFAULT, Vector2.DEFAULT); } /* static Rectangle2 from_arbitrary_corners(in Point2 corner1, in Point2 corner2) { } */ this(in Point2 position, in Vector2 size) { this(position.x, position.y, size.x, size.y); } this(in Point2 corner1, in Point2 corner2) { this(corner1.x, corner1.y, corner2.x - corner1.x, corner2.y - corner1.y); } Point2 position() const { return _position; } alias position min_corner; Point2 max_corner() const { return _position + _size; } bool valid() const { return _size.x > 0.0 & _size.y > 0.0; } bool invalid() const { return !valid(); } double area() const { return _size.x * _size.y; } // Intersection Rectangle2 opAnd(in Rectangle2 r) const { if (invalid() || r.invalid()) { return DEFAULT; } else { Point2 max = min_extents(max_corner(), r.max_corner()); Point2 min = max_extents(min_corner(), r.min_corner()); if (max.x < min.x || max.y < min.y) { return DEFAULT; } else { return Rectangle2(min, max); } } } // Union Rectangle2 opOr(in Rectangle2 r) const { if (invalid()) { return r; } else if (r.invalid()) { return this; } else { return Rectangle2(min_extents(min_corner(), r.min_corner()), max_extents(max_corner(), r.max_corner())); } } /* Rectangle2 moved(in Vector2 displacement) { return Rectangle2( } Rectangle2 resized(in Vector2 new_size) { } Rectangle2 repositioned(in Point2 new_position) { } */ string toString() /* const */ { return std.string.format("{%s, %s}", _position, _size); } private { this(double x, double y, double w, double h) { if (w < 0.0) { x += w; w = -w; } if (h < 0.0) { y += h; h = -h; } _position = Point2(x, y); _size = Vector2(w, h); } Point2 _position; Vector2 _size; } }