1 /**
2  * Segment
3  */
4 module d2d.math.Segment;
5 
6 import std.math;
7 import std.parallelism;
8 import d2d.math.AxisAlignedBoundingBox;
9 import d2d.math.Vector;
10 
11 /**
12  * A segment class that is defined by two 
13  */
14 class Segment(T, uint dimensions) {
15 
16     Vector!(T, dimensions) initial; ///The initial point (the vector points to the initial point)
17     Vector!(T, dimensions) terminal; ///The terminal point (the vector points to the terminal point)
18 
19     /**
20      * Returns the direction of the segment from initial to terminal
21      */
22     @property Vector!(T, dimensions) direction() {
23         return terminal - initial;
24     }
25 
26     /**
27      * Constructor for a segment;
28      * Takes in the initial point and the terminal point
29      */
30     this(Vector!(T, dimensions) initial, Vector!(T, dimensions) terminal) {
31         this.initial = initial;
32         this.terminal = terminal;
33     }
34 
35     /**
36      * Returns whether this segment contains the other point
37      * Checks that a segment from origin to point has magnitude between initial and terminal's magnitude
38      * Also checks that when point magnitude is 1 and direction magnitude is 1, they have the same or they have negated components
39      */
40     bool contains(T)(Vector!(T, dimensions) point) {
41         immutable pointMag = point.magnitude;
42         immutable initialMag = this.initial.magnitude;
43         immutable terminalMag = this.terminal.magnitude;
44         if (!(pointMag > initialMag && pointMag < terminalMag)
45                 && !(pointMag < initialMag && pointMag > terminalMag)) {
46             return false;
47         }
48         Vector!(T, dimensions) pointCopy = new Vector!(T, dimensions)(point);
49         Vector!(T, dimensions) direcCopy = this.direction;
50         pointCopy.magnitude = 1;
51         direcCopy.magnitude = 1;
52         return pointCopy == direcCopy || pointCopy == -direcCopy;
53     }
54 
55 }
56 
57 /**
58  * TODO: Returns where two segments intersect; if they don't intersect, returns null; needs rref of matrix to be completed first
59  */
60 Vector!(T, dimensions) interesction(T, dimensions)(Segment!(T,
61         dimensions) first, Segment!(T, dimensions) second) {
62     immutable dot = first.direction.dot(second.direction);
63     if (!intersects(new AxisAlignedBoundingBox(first.initial.first.terminal),
64             new AxisAlignedBoundingBox(first.initial.first.terminal)) || abs(dot).approxEquals(1)) {
65         return null;
66     }
67     return null;
68 }