// (C) 2011 Underground Software
// See the README and GPLv3 files for licensing and warranty information
//
-// JLH = James L. Hammons <jlhamm@acm.org>
+// JLH = James Hammons <jlhamm@acm.org>
//
// WHO WHEN WHAT
// --- ---------- ------------------------------------------------------------
#include <QtGui>
#include "dimension.h"
+#include "painter.h"
+
Line::Line(Vector p1, Vector p2, Object * p/*= NULL*/): Object(p1, p), endpoint(p2),
draggingLine(false), draggingHandle1(false), draggingHandle2(false), //needUpdate(false),
- length(Vector::Magnitude(p2, p1)), hitPoint1(false), hitPoint2(false), hitLine(false)
+ length(Vector::Magnitude(p2, p1)), angle(Vector(endpoint - position).Unit()),
+ hitPoint1(false), hitPoint2(false), hitLine(false)
{
}
// detached.
}
-/*virtual*/ void Line::Draw(QPainter * painter)
+/*virtual*/ void Line::Draw(Painter * painter)
{
- painter->setPen(QPen(Qt::red, 2.0, Qt::DotLine));
+ painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine));
if ((state == OSSelected) || ((state == OSInactive) && hitPoint1))
- painter->drawEllipse(QPointF(position.x, position.y), 4.0, 4.0);
+ painter->DrawHandle(position);
if ((state == OSSelected) || ((state == OSInactive) && hitPoint2))
- painter->drawEllipse(QPointF(endpoint.x, endpoint.y), 4.0, 4.0);
+ painter->DrawHandle(endpoint);
if ((state == OSInactive) && !hitLine)
- painter->setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
+ painter->SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
if (Object::fixedLength && (draggingHandle1 || draggingHandle2))
{
Vector current(point2 - point1);
Vector v = current.Unit() * length;
Vector v2 = point1 + v;
- painter->drawLine((int)point1.x, (int)point1.y, (int)v2.x, (int)v2.y);
+// painter->DrawLine((int)point1.x, (int)point1.y, (int)v2.x, (int)v2.y);
+ painter->DrawLine(point1, v2);
if (current.Magnitude() > length)
{
- painter->setPen(QPen(QColor(128, 0, 0), 1.0, Qt::DashLine));
- painter->drawLine((int)v2.x, (int)v2.y, (int)point2.x, (int)point2.y);
+ painter->SetPen(QPen(QColor(128, 0, 0), 1.0, Qt::DashLine));
+// painter->DrawLine((int)v2.x, (int)v2.y, (int)point2.x, (int)point2.y);
+ painter->DrawLine(v2, point2);
}
}
+// Problem: when drawing at large zoom levels, this throws away precision thus
+// causing the line to rendered too short. !!! FIX !!! [DONE]
else
- painter->drawLine((int)position.x, (int)position.y, (int)endpoint.x, (int)endpoint.y);
+// painter->DrawLine((int)position.x, (int)position.y, (int)endpoint.x, (int)endpoint.y);
+ painter->DrawLine(position, endpoint);
}
/*virtual*/ Vector Line::Center(void)
/*virtual*/ bool Line::Collided(Vector point)
{
-// Can't assume this!
-// Actually, we can, since this is a mouse down event here.
+ // We can assume this, since this is a mouse down event here.
objectWasDragged = false;
HitTest(point);
Arc, etc. and by giving the Dimension object a pointer to our endpoints.
Problem still arises when we delete this object; The attached Dimension object will
-then have bad pointers! What is *should* do is delete the object if and only if this
+then have bad pointers! What it *should* do is delete the object if and only if this
line is not attached to any other object. If it is, then one of those attachment
points should be sent to the dimension object (done for position & endpoint).
But we can fix that by making this object call any attached object's (like
a dimension only) Draw() function... :-/
*/
- attachedDimension = new Dimension(&position, &endpoint, this);
+ attachedDimension = new Dimension(&position, &endpoint, DTLinear, this);
if (parent != NULL)
parent->Add(attachedDimension);
Vector point1 = (draggingHandle1 ? endpoint : position);
Vector point2 = (draggingHandle1 ? position : endpoint);
+#if 0
Vector current(point2, point1);
Vector v = current.Unit() * length;
Vector v2 = point1 + v;
//bleh
if (!Object::fixedLength)
v2 = point2;
+#endif
+
+ if (Object::fixedAngle)
+ {
+ // Here we calculate the component of the current vector along the fixed angle.
+ // A_compB = (A . Bu) * Bu
+ double magnitudeAlongB = Vector::Dot(Vector(point2 - point1), angle);
+/*
+Actually, this isn't quite right. What we want to do is look for the intersection along either
+the horizontal line or vertical line that intersects from the current mouse position.
+*/
+
+ if (draggingHandle1)
+ position = endpoint + (angle * magnitudeAlongB);
+
+ if (draggingHandle2)
+ endpoint = position + (angle * magnitudeAlongB);
+ }
+// else
+// v2 = point2;
//If we tell the dimension to flip sides, this is no longer a valid
//assumption. !!! FIX !!!
// it turns out to have a fixed length. :-)
length = Vector(endpoint - position).Magnitude();
}
+
+ if (!Object::fixedAngle)
+ {
+ // Calculate the new angle, just in case on the next move it turns out to
+ // be fixed. :-)
+ angle = Vector(endpoint - position).Unit();
+ }
}
draggingLine = false;
state = oldState;
}
+// 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;
+}
+
#if 0
void Line::SetDimensionOnPoint1(Dimension * dimension)
{
// If they don't pass one in, create it for the caller.
if (dimension == NULL)
{
- dimension = new Dimension(&position, &endpoint, this);
+ dimension = new Dimension(&position, &endpoint, DTLinear, this);
if (parent)
parent->Add(dimension);
// 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 !!!"
- if (v1.Magnitude() < 8.0)
+//#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() < 8.0)
+ else if ((v2.Magnitude() * Painter::zoom) < 8.0)
hitPoint2 = true;
- else if (distance < 5.0)
+ else if ((distance * Painter::zoom) < 5.0)
hitLine = true;
return StateChanged();
t(d1x) - s(d2x) = p2x - p0x
t(d1y) - s(d2y) = p2y - p0y
-Determinant D is ad - bc where the matrix look like:
+Determinant D is ad - bc where the matrix looks like:
a b
c d