Mercurial > projects > doodle
view tk/geometry.d @ 4:58a8ad20b228
Ooops, this got left out of previous commit
author | David Bryant <daveb@acres.com.au> |
---|---|
date | Fri, 10 Jul 2009 15:26:07 +0930 |
parents | |
children | 71ca82e0eb76 |
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; } 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())); } } /* Rectangle moved(in Vector displacement) { return Rectangle( } Rectangle resized(in Vector new_size) { } Rectangle repositioned(in Point 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 = Point(x, y); _size = Vector(w, h); } Point _position; Vector _size; } }