+
+bool Line::HitTest(Point point)
+{
+ SaveState();
+
+ hitPoint1 = hitPoint2 = hitLine = false;
+ Vector lineSegment = endpoint - position;
+ Vector v1 = point - position;
+ Vector v2 = point - endpoint;
+ double parameterizedPoint = lineSegment.Dot(v1) / lineSegment.Magnitude(), distance;
+
+ // Geometric interpretation:
+ // The parameterized point on the vector lineSegment is where the perpendicular
+ // intersects lineSegment. If pp < 0, then the perpendicular lies beyond the 1st
+ // endpoint. If pp > length of ls, then the perpendicular lies beyond the 2nd endpoint.
+
+ if (parameterizedPoint < 0.0)
+ distance = v1.Magnitude();
+ else if (parameterizedPoint > lineSegment.Magnitude())
+ distance = v2.Magnitude();
+ else
+ // distance = ?Det?(ls, v1) / |ls|
+ distance = fabs((lineSegment.x * v1.y - v1.x * lineSegment.y) / lineSegment.Magnitude());
+
+ // Geometric interpretation of the above:
+ // If the segment endpoints are s and e, and the point is p, then the test
+ // for the perpendicular intercepting the segment is equivalent to insisting
+ // that the two dot products {s-e}.{s-p} and {e-s}.{e-p} are both non-negative.
+ // Perpendicular distance from the point to the segment is computed by first
+ // computing the area of the triangle the three points form, then dividing by
+ // the length of the segment. Distances are done just by the Pythagorean
+ // theorem. Twice the area of the triangle formed by three points is the
+ // determinant of the following matrix:
+ //
+ // sx sy 1 0 0 1 0 0 0
+ // ex ey 1 ==> ex ey 1 ==> ex ey 0
+ // px py 1 px py 1 px py 0
+ //
+ // By translating the start point to the origin, and subtracting row 1 from
+ // all other rows, we end up with the matrix on the right which greatly
+ // simplifies the calculation of the determinant.
+
+//How do we determine distance here? Especially if zoomed in or out???
+//#warning "!!! Distances tested for may not be valid if zoomed in or out !!!"
+// [FIXED]
+ if ((v1.Magnitude() * Painter::zoom) < 8.0)
+ hitPoint1 = true;
+ else if ((v2.Magnitude() * Painter::zoom) < 8.0)
+ hitPoint2 = true;
+ else if ((distance * Painter::zoom) < 5.0)
+ hitLine = true;
+
+ return StateChanged();
+}
+
+void Line::SaveState(void)
+{
+ oldHitPoint1 = hitPoint1;
+ oldHitPoint2 = hitPoint2;
+ oldHitLine = hitLine;
+}
+
+bool Line::StateChanged(void)
+{
+ if ((hitPoint1 != oldHitPoint1) || (hitPoint2 != oldHitPoint2) || (hitLine != oldHitLine))
+ return true;
+
+ return false;
+}
+
+/*
+Intersection of two lines:
+
+Find where the lines with equations r = i + j + t (3i - j) and r = -i + s (j) intersect.
+
+When they intersect, we can set the equations equal to one another:
+
+i + j + t (3i - j) = -i + s (j)
+
+Equating coefficients:
+1 + 3t = -1 and 1 - t = s
+So t = -2/3 and s = 5/3
+
+The position vector of the intersection point is therefore given by putting t = -2/3 or s = 5/3 into one of the above equations. This gives -i +5j/3 .
+
+
+so, let's say we have two lines, l1 and l2. Points are v0(p0x, p0y), v1(p1x, p1y) for l1
+and v2(p2x, p2y), v3(p3x, p3y) for l2.
+
+d1 = v1 - v0, d2 = v3 - v2
+
+Our parametric equations for the line then are:
+
+r1 = v0 + t(d1)
+r2 = v2 + s(d2)
+
+Set r1 = r2, thus we have:
+
+v0 + t(d1) = v2 + s(d2)
+
+Taking coefficients, we have:
+
+p0x + t(d1x) = p2x + s(d2x)
+p0y + t(d1y) = p2y + s(d2y)
+
+rearranging we get:
+
+t(d1x) - s(d2x) = p2x - p0x
+t(d1y) - s(d2y) = p2y - p0y
+
+Determinant D is ad - bc where the matrix looks like:
+
+a b
+c d
+
+so D = (d1x)(d2y) - (d2x)(d1y)
+if D = 0, the lines are parallel.
+Dx = (p2x - p0x)(d2y) - (d2x)(p2y - p0y)
+Dy = (d1x)(p2y - p0y) - (p2x - p0x)(d1y)
+t = Dx/D, s = Dy/D
+
+We only need to calculate t, as we can then multiply it by d1 to get the intersection point.
+
+---------------------------------------------------------------------------------------------------
+
+The first and most preferred method for intersection calculation is the perp-product calculation. There are two vectors, v1 and v2. Create a third vector vector between the starting points of these vectors, and calculate the perp product of v2 and the two other vectors. These two scalars have to be divided to get the mulitplication ratio of v1 to reach intersection point. So:
+
+v1 ( bx1 , by1 );
+v2 ( bx2 , by2 );
+v3 ( bx3 , by3 );
+
+Perp product is equal with dot product of normal of first vector and the second vector, so we need normals:
+
+n1 ( -by1 , bx1 );
+n3 ( -by3 , bx3 );
+
+Dot products:
+
+dp1 = n3 . v2 = -by3 * bx2 + bx3 * by2;
+dp2 = n1 . v2 = -by1 * bx2 + bx1 * by2;
+
+ratio = dp1 / dp2;
+crossing vector = v1 * ratio;
+
+And that's it.
+
+-----------------------------------
+
+So... to code this, let's say we have two Lines: l1 & l2.
+
+Vector v1 = l1.endpoint - l1.position;
+Vector v2 = l2.endpoint - l2.position;
+Vector v3 = v2 - v1;
+
+Vector normal1(-v1.y, v1.x);
+Vector normal3(-v3.y, v3.x);
+
+double dotProduct1 = v2.Dot(normal1);
+double dotProduct2 = v2.Dot(normal3);
+
+if (dotProduct2 == 0)
+ return ParallelLines;
+else
+{
+ // I think we'd still have to add the intersection to the position point to get the intersection...
+ Point intersection = v1 * (dotProduct1 / dotProduct2);
+ return intersection;
+}
+*/
+