+ return (hitPoint1 || hitPoint2 || hitLine ? true : false);
+// return HitStateChanged();
+}
+
+
+// Check to see if the point passed in coincides with any we have. If so, return a
+// pointer to it; otherwise, return NULL.
+/*virtual*/ Vector * Line::GetPointAt(Vector v)
+{
+ if (v == position)
+ return &position;
+ else if (v == endpoint)
+ return &endpoint;
+
+ return 0;
+}
+
+
+/*virtual*/ void Line::Enumerate(FILE * file)
+{
+ fprintf(file, "LINE %i (%lf,%lf) (%lf,%lf)\n", layer, position.x, position.y, endpoint.x, endpoint.y);
+}
+
+
+/*virtual*/ Object * Line::Copy(void)
+{
+#warning "!!! This doesn't take care of attached Dimensions !!!"
+/*
+This is a real problem. While having a pointer in the Dimension to this line's points
+is fast & easy, it creates a huge problem when trying to replicate an object like this.
+
+Maybe a way to fix that then, is to have reference numbers instead of pointers. That
+way, if you copy them, ... you might still have problems. Because you can't be sure if
+a copy will be persistant or not, you then *definitely* do not want them to have the
+same reference number.
+*/
+ return new Line(position, endpoint, parent);
+}
+
+
+/*virtual*/ Vector Line::GetPointAtParameter(double parameter)
+{
+ if (parameter <= 0)
+ return position;
+ else if (parameter >= 1.0)
+ return endpoint;
+
+ // Our parameter lies between zero and one, so calculate it!
+ Vector v(endpoint, position);
+ double length = v.Magnitude();
+ // We scale the magnitude of v so that it lies between 0 and 1...
+ // By multiplying the parameter by the magnitude, we obtain the point we
+ // want. No scaling necessary as it's inherent in the approach!
+ double spotOnLength = length * parameter;
+
+ // To get our point, we use the initial point of the line and add in our
+ // scaled point.
+ Vector result = position + (v * spotOnLength);
+ return result;
+}
+
+
+/*virtual*/ QRectF Line::Extents(void)
+{
+ QRectF rect(QPointF(position.x, position.y), QPointF(endpoint.x, endpoint.y));
+ return rect.normalized();
+}
+
+
+/*virtual*/ void Line::Translate(Vector amount)
+{
+ position += amount;
+ endpoint += amount;
+}
+
+
+/*virtual*/ void Line::Rotate(Vector point, double angle)
+{
+}
+
+
+/*virtual*/ void Line::Scale(Vector point, double amount)
+{
+}
+
+
+/*virtual*/ Object * Line::Mirror(Vector p1, Vector p2)
+{
+#if 1
+ Point l1 = Geometry::MirrorPointAroundLine(position, p1, p2);
+ Point l2 = Geometry::MirrorPointAroundLine(endpoint, p1, p2);
+ return new Line(l1, l2);
+#else
+ Vector normal = Vector::Normal(p1, p2);
+ Vector p4 = position + normal;
+
+ // Find the intersection of the line and position + normal to the line
+ double px = (((p1.x * p2.y) - (p1.y * p2.x)) * (position.x - p4.x))
+ - ((p1.x - p2.x) * ((position.x * p4.y) - (position.y * p4.x)));
+ double py = (((p1.x * p2.y) - (p1.y * p2.x)) * (position.y - p4.y))
+ - ((p1.y - p2.y) * ((position.x * p4.y) - (position.y * p4.x)));
+ double d = ((p1.x - p2.x) * (position.y - p4.y))
+ - ((p1.y - p2.y) * (position.x - p4.x));
+
+ // px = (x1y2 - y1x2)(x3 - x4) - (x1 - x2)(x3y4 - y3x4)
+ // py = (x1y2 - y1x2)(y3 - y4) - (y1 - y2)(x3y4 - y3x4)
+ // d = (x1 - x2)(y3 - y4) - (y1 - y2)(x3 - x4) = 0 if lines are parallel
+ // Intersection is (px / d, py / d)
+
+ Vector v1(px / d, py / d);
+
+// Vector normal = Vector::Normal(p1, p2);
+ p4 = endpoint + normal;
+
+ // Find the intersection of the line and endpoint + normal to the line
+ px = (((p1.x * p2.y) - (p1.y * p2.x)) * (endpoint.x - p4.x))
+ - ((p1.x - p2.x) * ((endpoint.x * p4.y) - (endpoint.y * p4.x)));
+ py = (((p1.x * p2.y) - (p1.y * p2.x)) * (endpoint.y - p4.y))
+ - ((p1.y - p2.y) * ((endpoint.x * p4.y) - (endpoint.y * p4.x)));
+ d = ((p1.x - p2.x) * (endpoint.y - p4.y))
+ - ((p1.y - p2.y) * (endpoint.x - p4.x));
+
+ Vector v2(px / d, py / d);
+
+#if 0
+ Vector v3 = position - v1;
+ Vector v4 = endpoint - v2;
+
+ Vector v5 = v1 + -v3;
+ Vector v6 = v2 + -v4;
+#else
+ Vector v5 = v1 + v1 - position;
+ Vector v6 = v2 + v2 - endpoint;
+#endif
+
+ return new Line(v5, v6);
+#endif
+}
+
+
+void Line::SetDimensionOnLine(Dimension * dimension/*=NULL*/)
+{
+ // If they don't pass one in, create it for the caller.
+ if (dimension == NULL)
+ {
+//printf("Line::SetDimensionOnLine(): Creating new dimension...\n");
+// dimension = new Dimension(position, endpoint, DTLinear, this);
+ dimension = new Dimension(Connection(this, 0), Connection(this, 1.0), DTLinear, this);
+
+ if (parent)
+//{
+//printf("Line::SetDimensionOnLine(): Adding to parent...\n");
+ parent->Add(dimension);
+//}
+ }
+ else
+ {
+ dimension->Connect(this, 0);
+ dimension->Connect(this, 1.0);
+ }
+
+ // Make sure the Dimension is connected to us...
+ Connect(dimension, 0);
+ Connect(dimension, 1.0);
+}
+
+
+Object * Line::FindAttachedDimension(void)
+{
+ // Is there anything connected to this line? If not, return NULL
+ if (connected.size() < 2)
+ return NULL;
+
+ // Otherwise, we have to search our objects to see if there's a likely
+ // candidate. In this case, we're looking for a pointer to the same object
+ // with a parameter of 0 and 1 respectively. This is O((n^2)/2).
+ for(uint i=0; i<connected.size(); i++)
+ {
+ for(uint j=i+1; j<connected.size(); j++)
+ {
+//printf("Line: connected[i]=%X, connected[j]=%X, connected[i].t=%lf, connected[j].t=%lf\n", connected[i].object, connected[j].object, connected[i].t, connected[j].t);
+ if ((connected[i].object == connected[j].object)
+ && ((connected[i].t == 0 && connected[j].t == 1.0)
+ || (connected[i].t == 1.0 && connected[j].t == 0)))
+ return connected[i].object;
+ }
+ }
+
+ // Didn't find anything, so return NULL
+ return NULL;