else
painter->setPen(QPen(Qt::blue, 1.0, Qt::SolidLine));
-#if 0
-// if (draggingHandle1)
- if (state == OSSelected)
- painter->drawEllipse(QPointF(position.x, position.y), 4.0, 4.0);
-
-// if (draggingHandle2)
- if (state == OSSelected)
- painter->drawEllipse(QPointF(endpoint.x, endpoint.y), 4.0, 4.0);
-
- if (Object::fixedLength && (draggingHandle1 || draggingHandle2))
- {
- Vector point1 = (draggingHandle1 ? endpoint : position);
- Vector point2 = (draggingHandle1 ? position : endpoint);
-
- 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);
-
- 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);
- }
- }
- else
- painter->drawLine((int)position.x, (int)position.y, (int)endpoint.x, (int)endpoint.y);
-#endif
// Draw an aligned dimension line
double angle = Vector(endpoint - position).Angle();
double orthoAngle = angle + (PI / 2.0);
Point ctr = p2 + v1;
QString dimText = QString("%1\"").arg(Vector(endpoint - position).Magnitude());
int textWidth = QFontMetrics(painter->font()).width(dimText);
+ int textHeight = QFontMetrics(painter->font()).height();
//We have to do transformation voodoo to make the text come out readable and in correct orientation...
//Some things to note here: if angle > 90 degrees, then we need to take the negative of the angle
//for our text.
painter->save();
painter->translate(ctr.x, ctr.y);
+int yOffset = -8;
+//16 : printf("textHeight: %d\n", textHeight);
+
+//Fix text so it isn't upside down...
+if ((angle > PI * 0.5) && (angle < PI * 1.5))
+{
+ angle += PI;
+ yOffset = 18;
+}
+
painter->rotate(angle * RADIANS_TO_DEGREES);
painter->scale(1.0, -1.0);
//painter->translate(-textWidth / 2, -24);
// painter->drawText(0, 0, textWidth, 20, Qt::AlignCenter, dimText);
// This version draws the y-coord from the baseline of the font
- painter->drawText(-textWidth / 2, -8, dimText);
+ painter->drawText(-textWidth / 2, yOffset, dimText);
//painter->setPen(QPen(QColor(0xFF, 0x20, 0x20), 1.0, Qt::SolidLine));
//painter->drawLine(20, 0, -20, 0);
//painter->drawLine(0, 20, 0, -20);
if (objectWasDragged)
state = oldState;
}
+
+void Dimension::SetPoint1(Vector v)
+{
+ position = v;
+ needUpdate = true;
+}
+
+void Dimension::SetPoint2(Vector v)
+{
+ endpoint = v;
+ needUpdate = true;
+}
virtual bool Collided(Vector);
virtual void PointerMoved(Vector);
virtual void PointerReleased(void);
-// virtual bool NeedsUpdate(void);
+ void SetPoint1(Vector);
+ void SetPoint2(Vector);
protected:
Vector endpoint; // Starting point is Object::position
bool dragging;
bool draggingHandle1;
bool draggingHandle2;
-// bool needUpdate;
bool objectWasDragged;
double length;
};
// setCursor(cur[TOOLSelect]);
// setMouseTracking(true);
- document.Add(new Line(Vector(5, 5), Vector(50, 40), &document));
+ Line * line = new Line(Vector(5, 5), Vector(50, 40), &document);
+ document.Add(line);
document.Add(new Line(Vector(50, 40), Vector(10, 83), &document));
document.Add(new Line(Vector(10, 83), Vector(17, 2), &document));
document.Add(new Circle(Vector(100, 100), 36, &document));
document.Add(new Circle(Vector(50, 150), 49, &document));
document.Add(new Arc(Vector(300, 300), 32, PI / 4.0, PI * 1.3, &document)),
document.Add(new Arc(Vector(200, 200), 60, PI / 2.0, PI * 1.5, &document));
- document.Add(new Dimension(Vector(5, 5), Vector(50, 40), &document));
+ Dimension * dimension = new Dimension(Vector(0, 0), Vector(0, 0), &document);
+ line->SetDimensionOnPoint1(dimension);
+ line->SetDimensionOnPoint2(dimension);
+ document.Add(dimension);
}
QPoint DrawingView::GetAdjustedMousePosition(QMouseEvent * event)
// WHO WHEN WHAT
// --- ---------- ------------------------------------------------------------
// JLH 03/22/2011 Created this file
+// JLH 04/11/2011 Fixed attached dimensions to stay at correct length when
+// "Fixed Length" button is down
//
#include "line.h"
#include <QtGui>
+#include "dimension.h"
Line::Line(Vector p1, Vector p2, Object * p/*= NULL*/): Object(p1, p), endpoint(p2),
dragging(false), draggingHandle1(false), draggingHandle2(false), //needUpdate(false),
}
else
needUpdate = false;
+
+ if (needUpdate)
+ {
+// should only do this if "Fixed Length" is set... !!! FIX !!!
+ Vector point1 = (draggingHandle1 ? endpoint : position);
+ Vector point2 = (draggingHandle1 ? position : endpoint);
+
+ Vector current(point2 - point1);
+ Vector v = current.Unit() * length;
+ Vector v2 = point1 + v;
+
+ if (dimPoint1)
+ dimPoint1->SetPoint1(draggingHandle1 ? v2 : position);
+
+ if (dimPoint2)
+ dimPoint2->SetPoint2(draggingHandle2 ? v2 : endpoint);
+ }
}
/*virtual*/ void Line::PointerReleased(void)
state = oldState;
}
-#if 0
-/*virtual*/ bool Line::NeedsUpdate(void)
+void Line::SetDimensionOnPoint1(Dimension * dimension)
+{
+ dimPoint1 = dimension;
+
+ if (dimension)
+ dimension->SetPoint1(position);
+}
+
+void Line::SetDimensionOnPoint2(Dimension * dimension)
{
- return needUpdate;
+ dimPoint2 = dimension;
+
+ if (dimension)
+ dimension->SetPoint2(endpoint);
}
-#endif
+
+/*
+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 look 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*rat;
+
+And that's it.
+*/
+
#include "object.h"
+class Dimension;
+
class Line: public Object
{
public:
virtual bool Collided(Vector);
virtual void PointerMoved(Vector);
virtual void PointerReleased(void);
-// virtual bool NeedsUpdate(void);
+ void SetDimensionOnPoint1(Dimension *);
+ void SetDimensionOnPoint2(Dimension *);
protected:
Vector endpoint; // Starting point is Object::position
bool dragging;
bool draggingHandle1;
bool draggingHandle2;
-// bool needUpdate;
bool objectWasDragged;
double length;
};
Object::Object(): position(Vector(0, 0)), parent(0), state(OSInactive), oldState(OSInactive),
- needUpdate(false)
+ needUpdate(false), dimPoint1(0), dimPoint2(0)
{
}
Object::Object(Vector v, Object * passedInParent/*= 0*/): position(v), parent(passedInParent),
- state(OSInactive), oldState(OSInactive), needUpdate(false)
+ state(OSInactive), oldState(OSInactive), needUpdate(false), dimPoint1(0), dimPoint2(0)
{
}
return needUpdate;
}
+// This is intended to be overridden by the Container class, for object morphing
+/*virtual*/ void Object::Transmute(Object *, Object *)
+{
+}
+
ObjectState Object::GetState(void)
{
return state;
class QPainter;
class QFont;
+class Dimension;
enum ObjectState { OSInactive, OSSelected };
virtual void PointerMoved(Vector);
virtual void PointerReleased(void);
virtual bool NeedsUpdate(void);
-
+ virtual void Transmute(Object *, Object *);
ObjectState GetState(void);
// Class methods
ObjectState state;
ObjectState oldState;
bool needUpdate;
+ Dimension * dimPoint1;
+ Dimension * dimPoint2;
// Class variables
static QFont * font;