From: Shamus Hammons Date: Sun, 1 Sep 2013 20:38:25 +0000 (-0500) Subject: Mirror tool now works successfully for all object types. :-D X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=architektonas;a=commitdiff_plain;h=67fbc130b4b6b4d253f69a9c32980d3d3306def5 Mirror tool now works successfully for all object types. :-D --- diff --git a/.gitignore b/.gitignore index 090323f..2c5004a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ res.old/* *.ui pix/* res/*.xcf +dxflib/ +fparser/ +architektonas diff --git a/TODO b/TODO index 355ea29..13ab43c 100644 --- 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.) diff --git a/src/arc.cpp b/src/arc.cpp index b0e3b72..f7cde52 100644 --- a/src/arc.cpp +++ b/src/arc.cpp @@ -16,6 +16,7 @@ #include "arc.h" #include +#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; +} + diff --git a/src/arc.h b/src/arc.h index a05a259..da0a6ea 100644 --- 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 diff --git a/src/circle.cpp b/src/circle.cpp index e73bcdc..b722f4d 100644 --- a/src/circle.cpp +++ b/src/circle.cpp @@ -16,6 +16,7 @@ #include "circle.h" #include +#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; +} + diff --git a/src/circle.h b/src/circle.h index b12ae99..6fd22cd 100644 --- a/src/circle.h +++ b/src/circle.h @@ -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; diff --git a/src/container.cpp b/src/container.cpp index 77d1771..e8a66e4 100644 --- a/src/container.cpp +++ b/src/container.cpp @@ -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::iterator i=objects.begin(); i!=objects.end(); i++) + { + if ((*i)->state == OSSelected) + newContainer->Add((*i)->Copy()); + } +} + + void Container::ResizeAllDimensions(double newSize) { for(std::vector::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::iterator i=objects.begin(); i!=objects.end(); i++) + (*i)->Mirror(p1, p2); +} + + +/*virtual*/ void Container::Save(void) +{ + Object::Save(); + + for(std::vector::iterator i=objects.begin(); i!=objects.end(); i++) + (*i)->Save(); +} + + +/*virtual*/ void Container::Restore(void) +{ + Object::Restore(); + + for(std::vector::iterator i=objects.begin(); i!=objects.end(); i++) + (*i)->Restore(); +} + diff --git a/src/container.h b/src/container.h index 905e757..f4e48e6 100644 --- a/src/container.h +++ b/src/container.h @@ -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: diff --git a/src/line.cpp b/src/line.cpp index 956b9bd..b7abc9a 100644 --- a/src/line.cpp +++ b/src/line.cpp @@ -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; } diff --git a/src/line.h b/src/line.h index cc048a8..5d84b39 100644 --- a/src/line.h +++ b/src/line.h @@ -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; diff --git a/src/mirroraction.cpp b/src/mirroraction.cpp index 720692e..af786d7 100644 --- a/src/mirroraction.cpp +++ b/src/mirroraction.cpp @@ -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::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::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 & objs = ApplicationWindow::drawing->document.objects; + + for(std::vector::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(); } } diff --git a/src/mirroraction.h b/src/mirroraction.h index 2198a88..caeda0d 100644 --- a/src/mirroraction.h +++ b/src/mirroraction.h @@ -24,6 +24,7 @@ class MirrorAction: public Action Line * line; Vector p1, p2, p1Save; bool shiftWasPressedOnNextPoint; +// Container * selected; Container * mirror; }; diff --git a/src/object.cpp b/src/object.cpp index dd80007..a3ff1ac 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -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; } diff --git a/src/object.h b/src/object.h index 2cdd3d3..d34e79a 100644 --- a/src/object.h +++ b/src/object.h @@ -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;