]> Shamusworld >> Repos - architektonas/commitdiff
Mirror tool now works successfully for all object types. :-D
authorShamus Hammons <jlhamm@acm.org>
Sun, 1 Sep 2013 20:38:25 +0000 (15:38 -0500)
committerShamus Hammons <jlhamm@acm.org>
Sun, 1 Sep 2013 20:38:25 +0000 (15:38 -0500)
14 files changed:
.gitignore
TODO
src/arc.cpp
src/arc.h
src/circle.cpp
src/circle.h
src/container.cpp
src/container.h
src/line.cpp
src/line.h
src/mirroraction.cpp
src/mirroraction.h
src/object.cpp
src/object.h

index 090323f3ac84f82b888d9b6815d3ecd690dadba1..2c5004a00aaed97d58c5530c3c1bfe35c1e45000 100644 (file)
@@ -6,3 +6,6 @@ res.old/*
 *.ui
 pix/*
 res/*.xcf
+dxflib/
+fparser/
+architektonas
diff --git a/TODO b/TODO
index 355ea29779ae11dcde66a5eeddde9f1e46686937..13ab43c7997f13ad3b8c7c540437545f9632a88e 100644 (file)
--- a/TODO
+++ b/TODO
@@ -6,7 +6,7 @@ Stuff To Be Implemented/Fixed
  - Add Spline
  - Add Text
  - Manipulate Dimension
- - Object connections
+ - Object connections (two types: flexible and rigid)
  - Group selection (kind done, needs more work though)
  - Take movement code out of Objects and put it into top level Container (actually
    I think this should be more of the state code handling. Have to see.)
index b0e3b720148bd502f6cc1eb425972d6e111a8cfc..f7cde5283c8befbf01926979e787d9afa1aa8c6b 100644 (file)
@@ -16,6 +16,7 @@
 #include "arc.h"
 
 #include <QtGui>
+#include "geometry.h"
 #include "mathconstants.h"
 #include "painter.h"
 
@@ -151,6 +152,10 @@ Also: should put the snap logic into the Object base class (as a static method).
 
 /*virtual*/ bool Arc::Collided(Vector point)
 {
+       // Someone told us to fuck off, so we'll fuck off. :-)
+       if (ignoreClicks)
+               return false;
+
        objectWasDragged = false;
        bool hitSomething = HitTest(point);
        draggingCenter = hitCenter;
@@ -450,3 +455,33 @@ same reference number.
        return new Arc(position, radius, startAngle, angleSpan, parent);
 }
 
+
+/*virtual*/ void Arc::Mirror(Point p1, Point p2)
+{
+       Point c1 = Geometry::MirrorPointAroundLine(position, p1, p2);
+       Point ap1(cos(startAngle + angleSpan), sin(startAngle + angleSpan));
+       Point angleEndPoint = (ap1 * radius) + position;
+       Point c2 = Geometry::MirrorPointAroundLine(angleEndPoint, p1, p2);
+
+       position = c1;
+       startAngle = Vector(c2, c1).Angle();
+}
+
+
+/*virtual*/ void Arc::Save(void)
+{
+       Object::Save();
+       oldRadius2 = radius;
+       oldStartAngle = startAngle;
+       oldAngleSpan = angleSpan;
+}
+
+
+/*virtual*/ void Arc::Restore(void)
+{
+       Object::Restore();
+       radius = oldRadius2;
+       startAngle = oldStartAngle;
+       angleSpan = oldAngleSpan;
+}
+
index a05a259bd640951ed9530d1d4cc020d1cb98d800..da0a6ea674375e037bbe33807ef4bf4544824504 100644 (file)
--- a/src/arc.h
+++ b/src/arc.h
@@ -18,6 +18,9 @@ class Arc: public Object
                virtual void Enumerate(FILE *);
                virtual Object * Copy(void);
                virtual QRectF Extents(void);
+               virtual void Mirror(Point, Point);
+               virtual void Save(void);
+               virtual void Restore(void);
 
        private:
                bool AngleInArcSpan(double angle);
@@ -30,6 +33,9 @@ class Arc: public Object
                double radius;                                          // Center is Object::position
                double startAngle;                                      // Starting angle in radians
                double angleSpan;                                       // # of degrees the arc spans in radians
+               double oldRadius2;
+               double oldStartAngle;
+               double oldAngleSpan;
 
        private:
 //             bool hitHandle1;        // Moving
index e73bcdc9607fb6dd209a088e87bfb5d696062a35..b722f4d390a3c290ec6a68338b6591ebc061497a 100644 (file)
@@ -16,6 +16,7 @@
 #include "circle.h"
 
 #include <QtGui>
+#include "geometry.h"
 #include "painter.h"
 
 
@@ -86,6 +87,10 @@ Circle::~Circle()
 
 /*virtual*/ bool Circle::Collided(Vector point)
 {
+       // Someone told us to fuck off, so we'll fuck off. :-)
+       if (ignoreClicks)
+               return false;
+
        // We can assume this, since this is a mouse down event here.
        objectWasDragged = false;
        HitTest(point);
@@ -237,3 +242,25 @@ same reference number.
        return new Circle(position, radius, parent);
 }
 
+
+/*virtual*/ void Circle::Mirror(Point p1, Point p2)
+{
+       Point c1 = Geometry::MirrorPointAroundLine(position, p1, p2);
+//     return new Circle(c1, radius);
+       position = c1;
+}
+
+
+/*virtual*/ void Circle::Save(void)
+{
+       Object::Save();
+       oldRadius2 = radius;
+}
+
+
+/*virtual*/ void Circle::Restore(void)
+{
+       Object::Restore();
+       radius = oldRadius2;
+}
+
index b12ae99d44b1346f36c9ed16d76ec627de537f4a..6fd22cd615dcbeb89fc3f61381206babe0631bee 100644 (file)
@@ -18,6 +18,9 @@ class Circle: public Object
                virtual void Enumerate(FILE *);
                virtual Object * Copy(void);
                virtual QRectF Extents(void);
+               virtual void Mirror(Point, Point);
+               virtual void Save(void);
+               virtual void Restore(void);
 
        protected:
                void SaveHitState(void);
@@ -26,6 +29,7 @@ class Circle: public Object
        protected:
                double radius;                                          // Center is Object::position
                Vector dragPoint;                                       // Used for rendering edge dragging
+               double oldRadius2;
 
        private:
                bool draggingEdge;
index 77d1771416d47ae112be9c1e74fd5d663a408200..e8a66e4d3ba040a178c7eadefc6a5c855adc6aa2 100644 (file)
@@ -22,7 +22,8 @@
 
 Container::Container(Vector p1, Object * p/*= NULL*/): Object(p1, p),
        isTopLevelContainer(false),
-       dragging(false), draggingHandle1(false), draggingHandle2(false)//, needUpdate(false)
+       dragging(false), draggingHandle1(false), draggingHandle2(false),
+       hit(false)//, needUpdate(false)
 {
        type = OTContainer;
        state = OSInactive;
@@ -475,6 +476,21 @@ void Container::MoveSelectedContentsTo(Container * newContainer)
 }
 
 
+void Container::CopySelectedContentsTo(Container * newContainer)
+{
+       // Sanity check
+       if (newContainer == NULL)
+               return;
+
+       // Shuffle the contents of this container to the new one
+       for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
+       {
+               if ((*i)->state == OSSelected)
+                       newContainer->Add((*i)->Copy());
+       }
+}
+
+
 void Container::ResizeAllDimensions(double newSize)
 {
        for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
@@ -520,3 +536,28 @@ same reference number.
        return c;
 }
 
+
+/*virtual*/ void Container::Mirror(Point p1, Point p2)
+{
+       for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
+               (*i)->Mirror(p1, p2);
+}
+
+
+/*virtual*/ void Container::Save(void)
+{
+       Object::Save();
+
+       for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
+               (*i)->Save();
+}
+
+
+/*virtual*/ void Container::Restore(void)
+{
+       Object::Restore();
+
+       for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
+               (*i)->Restore();
+}
+
index 905e7572fab7ca8c31ab5688ecd48544dd2ef985..f4e48e6be39ed8c9fd3d1cdf4e9d4e5ae4037bf9 100644 (file)
@@ -23,6 +23,9 @@ class Container: public Object
                virtual QRectF Extents(void);
                virtual void Enumerate(FILE *);
                virtual Object * Copy(void);
+               virtual void Mirror(Point, Point);
+               virtual void Save(void);
+               virtual void Restore(void);
                void Delete(Object *);
                void DeleteSelectedItems(void);
                void Clear(void);
@@ -32,6 +35,7 @@ class Container: public Object
                Object * SelectedItem(unsigned int);
                void MoveContentsTo(Container *);
                void MoveSelectedContentsTo(Container *);
+               void CopySelectedContentsTo(Container *);
                void ResizeAllDimensions(double);
 
        protected:
index 956b9bdd3c7174c16041885ed43100e758f2ff67..b7abc9ad6bb62939cb9ddd5102a65d25d7bcadf3 100644 (file)
@@ -581,57 +581,26 @@ same reference number.
 }
 
 
-/*virtual*/ Object * Line::Mirror(Vector p1, Vector p2)
+/*virtual*/ void Line::Mirror(Point p1, Point 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));
+       position = l1;
+       endpoint = l2;
+}
 
-       Vector v2(px / d, py / d);
 
-#if 0
-       Vector v3 = position - v1;
-       Vector v4 = endpoint - v2;
+/*virtual*/ void Line::Save(void)
+{
+       Object::Save();
+       oldEndpoint = endpoint;
+}
 
-       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
+/*virtual*/ void Line::Restore(void)
+{
+       Object::Restore();
+       endpoint = oldEndpoint;
 }
 
 
index cc048a8281b90359b75976c57c4cfe9ad90de770..5d84b39bf9128ab1bf69f27bea9ec5ed2660b5af 100644 (file)
@@ -22,11 +22,12 @@ class Line: public Object
                virtual Object * Copy(void);
                virtual Vector GetPointAtParameter(double parameter);
                virtual QRectF Extents(void);
-//             virtual ObjectType Type(void);
                virtual void Translate(Vector);
                virtual void Rotate(Vector, double);
                virtual void Scale(Vector, double);
-               virtual Object * Mirror(Vector, Vector);
+               virtual void Mirror(Point, Point);
+               virtual void Save(void);
+               virtual void Restore(void);
                void SetDimensionOnLine(Dimension * d = 0);
                Object * FindAttachedDimension(void);
 
@@ -37,6 +38,7 @@ class Line: public Object
        protected:
                Vector endpoint;                                        // Starting point is Object::position
                Vector oldPoint;                                        // Used for dragging
+               Point oldEndpoint;
 
        private:
                bool draggingLine;
index 720692ed85130725ac3c2170206fa2ec251463ea..af786d7f1dc72393c3698cd09b3af38b69bf1098 100644 (file)
@@ -29,6 +29,12 @@ enum { FIRST_POINT, NEXT_POINT };
 MirrorAction::MirrorAction(): state(FIRST_POINT), line(NULL),
        shiftWasPressedOnNextPoint(false), mirror(new Container(Vector()))
 {
+//     ApplicationWindow::drawing->document.CopySelectedContentsTo(selected);
+       ApplicationWindow::drawing->document.CopySelectedContentsTo(mirror);
+
+//     for(std::vector<Object *>::iterator i=mirror->objects.begin(); i!=mirror->objects.end(); i++)
+//             (*i)->Save();
+       mirror->Save();
 }
 
 
@@ -49,11 +55,16 @@ MirrorAction::~MirrorAction()
        }
        else
        {
-               painter->DrawLine(p1, p2);
-               painter->DrawHandle(p2);
+               Vector reflectedP2 = -(p2 - p1);
+               Point newP2 = p1 + reflectedP2;
+               painter->DrawLine(newP2, p2);
+               painter->DrawHandle(p1);
 
                double absAngle = (Vector(p2 - p1).Angle()) * RADIANS_TO_DEGREES;
-//             double absLength = Vector(position - endpoint).Magnitude();
+
+               // Keep the angle between 0 and 180 degrees
+               if (absAngle > 180.0)
+                       absAngle -= 180.0;
 
                QString text = QChar(0x2221) + QObject::tr(": %1");
                text = text.arg(absAngle);
@@ -61,7 +72,9 @@ MirrorAction::~MirrorAction()
 //             text = text.arg(Vector::Magnitude(p1, p2));
                painter->DrawInformativeText(text);
 
-               mirror->Draw(painter);
+               // Draw the mirror only if there's been a line to mirror around
+               if (p1 != p2)
+                       mirror->Draw(painter);
        }
 }
 
@@ -86,17 +99,10 @@ MirrorAction::~MirrorAction()
        {
                p2 = point;
 
-               mirror->Clear();
-               int itemsSelected = ApplicationWindow::drawing->document.ItemsSelected();
-
-               if (itemsSelected == 0)
-                       return;
-
-               for(int i=0; i<itemsSelected; i++)
+               for(std::vector<Object *>::iterator i=mirror->objects.begin(); i!=mirror->objects.end(); i++)
                {
-                       Object * object = ApplicationWindow::drawing->document.SelectedItem(i);
-                       Object * mirrored = object->Mirror(p1, p2);
-                       mirror->Add(mirrored);
+                       (*i)->Restore();
+                       (*i)->Mirror(p1, p2);
                }
        }
 }
@@ -111,14 +117,19 @@ MirrorAction::~MirrorAction()
        }
        else if (state == NEXT_POINT)
        {
-               // We create the new object here, and then pass it off to the
-               // DrawingView which stuffs it into the document.
-//             line = new Line(p1, p2);
-               // We don't need no stinkin' sentinels, when we have signals & slots!
-//             emit ObjectReady(line);
+               state = FIRST_POINT;
 
-               p1 = p2;
-               state = NEXT_POINT;
+               std::vector<Object *> & objs = ApplicationWindow::drawing->document.objects;
+
+               for(std::vector<Object *>::iterator i=objs.begin(); i!=objs.end(); i++)
+               {
+                       if ((*i)->state == OSSelected)
+                               (*i)->Mirror(p1, p2);
+               }
+
+               mirror->Clear();
+               ApplicationWindow::drawing->document.CopySelectedContentsTo(mirror);
+               mirror->Save();
        }
 }
 
index 2198a88e4a6543220b91a07cefb0477c0abcdc3d..caeda0d4d3ae5c6bf6a51ae354c26d463fdc9f54 100644 (file)
@@ -24,6 +24,7 @@ class MirrorAction: public Action
                Line * line;
                Vector p1, p2, p1Save;
                bool shiftWasPressedOnNextPoint;
+//             Container * selected;
                Container * mirror;
 };
 
index dd80007d1998cc4c4772848c35580a53fe2f9859..a3ff1ac945705dd427f18bce3c988a52fe4cadc4 100644 (file)
@@ -234,9 +234,20 @@ printf("Object: Destroyed!\n");
 }
 
 
-/*virtual*/ Object * Object::Mirror(Vector, Vector)
+/*virtual*/ void Object::Mirror(Point, Point)
 {
-       return NULL;
+}
+
+
+/*virtual*/ void Object::Save(void)
+{
+       oldPosition = position;
+}
+
+
+/*virtual*/ void Object::Restore(void)
+{
+       position = oldPosition;
 }
 
 
index 2cdd3d36863e09fdeef2e837487be7cf87b86f7f..d34e79ae7598df74e85b3d330f63a390a9aeafe4 100644 (file)
@@ -44,7 +44,9 @@ class Object
                virtual void Translate(Vector);
                virtual void Rotate(Vector, double);
                virtual void Scale(Vector, double);
-               virtual Object * Mirror(Vector, Vector);
+               virtual void Mirror(Point, Point);
+               virtual void Save(void);
+               virtual void Restore(void);
                ObjectState GetState(void);
                void Reparent(Object *);
 //             Dimension * GetAttachedDimension(void);
@@ -65,6 +67,7 @@ class Object
                Object * parent;
 //             Pen pen;
 //             Fill fill;
+               Point oldPosition;
        public:
                ObjectType type;
                ObjectState state;