changeset 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 7d57cae10805
children 8a39b13cd3e6
files tk/geometry.d
diffstat 1 files changed, 198 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tk/geometry.d	Fri Jul 10 15:26:07 2009 +0930
@@ -0,0 +1,198 @@
+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;
+    }
+}