Mercurial > projects > doodle
view tk/geometry.d @ 15:2f79aab4d385
Checkpoint
author | "David Bryant <bagnose@gmail.com>" |
---|---|
date | Sun, 12 Jul 2009 13:23:06 +0930 |
parents | f0ade1b49fe7 |
children | 9e63308b749c |
line wrap: on
line source
module tk.geometry; private import std.stdio; private import std.math; private import tk.misc; struct Point { static immutable Point DEFAULT; static this() { DEFAULT = Point(0.0, 0.0); } this(in double x, in double y) { _x = x; _y = y; } Point opAdd(in Vector v) const { return Point(_x + v._x, _y + v._y); } Point opSub(in Vector v) const { return Point(_x - v._x, _y - v._y); } Vector opSub(in Point p) const { return Vector(_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; } } Point min_extents(in Point a, in Point b) { return Point(min(a.x, b.x), min(a.y, b.y)); } Point max_extents(in Point a, in Point b) { return Point(max(a.x, b.x), max(a.y, b.y)); } struct Vector { static Vector DEFAULT; static this() { DEFAULT = Vector(0.0, 0.0); } this(in double x, in double y) { _x = x; _y = y; } Vector opAdd(in Vector v) const { return Vector(_x + v._x, _y + v._y); } Vector opSub(in Vector v) const { return Vector(_x - v._x, _y - v._y); } Vector opNeg() const { return Vector(-_x, -_y); } Vector opMul_r(in double d) const { return Vector(d * _x, d * _y); } Vector opDiv(in double d) const { return Vector(_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 Rectangle { static Rectangle DEFAULT; static this() { DEFAULT = Rectangle(Point.DEFAULT, Vector.DEFAULT); } /* static Rectangle from_arbitrary_corners(in Point corner1, in Point corner) { } */ this(in Point position, in Vector size) { this(position.x, position.y, size.x, size.y); } this(in Point corner1, in Point corner) { this(corner1.x, corner1.y, corner.x - corner1.x, corner.y - corner1.y); } Point position() const { return _position; } Vector size() const { return _size; } alias position min_corner; Point 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 Rectangle opAnd(in Rectangle r) const { if (invalid() || r.invalid()) { return DEFAULT; } else { Point max = min_extents(max_corner(), r.max_corner()); Point min = max_extents(min_corner(), r.min_corner()); if (max.x < min.x || max.y < min.y) { return DEFAULT; } else { return Rectangle(min, max); } } } // Union Rectangle opOr(in Rectangle r) const { if (invalid()) { return r; } else if (r.invalid()) { return this; } else { return Rectangle(min_extents(min_corner(), r.min_corner()), max_extents(max_corner(), r.max_corner())); } } // TODO make these free functions Rectangle moved(in Vector displacement) const { return Rectangle(_position + displacement, _size); } Rectangle expanded(in Vector expand_amount) const { return Rectangle(_position, _size + expand_amount); } Rectangle shrunk(in Vector shrink_amount) const { return Rectangle(_position, _size - shrink_amount); } Rectangle resized(in Vector new_size) const { return Rectangle(_position, new_size); } Rectangle repositioned(in Point new_position) const { return Rectangle(new_position, _size); } Point centre() const { return _position + _size / 2.0; } 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 = Point(x, y); _size = Vector(w, h); } Point _position; Vector _size; } }