]> Shamusworld >> Repos - architektonas/commitdiff
Fixed Line rendering to keep attached Dimensions correct length with 'Fix Len'
authorShamus Hammons <jlhamm@acm.org>
Tue, 12 Apr 2011 00:36:32 +0000 (00:36 +0000)
committerShamus Hammons <jlhamm@acm.org>
Tue, 12 Apr 2011 00:36:32 +0000 (00:36 +0000)
src/dimension.cpp
src/dimension.h
src/drawingview.cpp
src/line.cpp
src/line.h
src/object.cpp
src/object.h

index d049fc32da0316336c4ba0414bce1cd2e8de5e9a..381196b00e37993ec204b277afa31ad2e03a36ce 100644 (file)
@@ -34,34 +34,6 @@ Dimension::~Dimension()
        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);
@@ -90,17 +62,28 @@ Dimension::~Dimension()
        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);
@@ -295,3 +278,15 @@ about keeping track of old states...
        if (objectWasDragged)
                state = oldState;
 }
+
+void Dimension::SetPoint1(Vector v)
+{
+       position = v;
+       needUpdate = true;
+}
+
+void Dimension::SetPoint2(Vector v)
+{
+       endpoint = v;
+       needUpdate = true;
+}
index 26fc58800fa5423546ee5451869b8908e1303ac9..34084c26af291a8d31e4bf70aacf58acc1e9f25a 100644 (file)
@@ -14,7 +14,8 @@ class Dimension: public Object
                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
@@ -24,7 +25,6 @@ class Dimension: public Object
                bool dragging;
                bool draggingHandle1;
                bool draggingHandle2;
-//             bool needUpdate;
                bool objectWasDragged;
                double length;
 };
index 911b2bac0cbeb232ccfa438e4e1e8b49d560b2bb..55b56e7d87e02ae0aa5cbd1b1e4c428ffca9ebb2 100644 (file)
@@ -50,14 +50,18 @@ DrawingView::DrawingView(QWidget * parent/*= NULL*/): QWidget(parent),
 //     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)
index b78a9dc6cd4f578a4e8d02cfe82adfe588797168..b7a11fb2cb300fa0c2c6cddd8220f712cb0ccedc 100644 (file)
@@ -9,11 +9,14 @@
 // 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),
@@ -203,6 +206,23 @@ Like so:
        }
        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)
@@ -247,9 +267,96 @@ about keeping track of old states...
                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.
+*/
+
index 1a38fa337ef73d49caf9fac1e0ad7b66284a2ea2..8d79c1fb0efb950d6faa0f4556f3168398bf2671 100644 (file)
@@ -3,6 +3,8 @@
 
 #include "object.h"
 
+class Dimension;
+
 class Line: public Object
 {
        public:
@@ -14,7 +16,8 @@ class Line: public Object
                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
@@ -24,7 +27,6 @@ class Line: public Object
                bool dragging;
                bool draggingHandle1;
                bool draggingHandle2;
-//             bool needUpdate;
                bool objectWasDragged;
                double length;
 };
index c2e874c415ed56db511c90dd6a5db05a03a4203e..eaef4d4484eb9d002d34777354554704cac985b7 100644 (file)
@@ -24,12 +24,12 @@ int Object::viewportHeight = 0;
 
 
 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)
 {
 }
 
@@ -64,6 +64,11 @@ Object::~Object()
        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;
index e0ea740460bbb83b71bece85b2272e303b82afa1..deaa91f3604f923b16a805fd57ccc55e241ca749 100644 (file)
@@ -5,6 +5,7 @@
 
 class QPainter;
 class QFont;
+class Dimension;
 
 enum ObjectState { OSInactive, OSSelected };
 
@@ -21,7 +22,7 @@ class Object
                virtual void PointerMoved(Vector);
                virtual void PointerReleased(void);
                virtual bool NeedsUpdate(void);
-
+               virtual void Transmute(Object *, Object *);
                ObjectState GetState(void);
 
                // Class methods
@@ -38,6 +39,8 @@ class Object
                ObjectState state;
                ObjectState oldState;
                bool needUpdate;
+               Dimension * dimPoint1;
+               Dimension * dimPoint2;
 
                // Class variables
                static QFont * font;