]> Shamusworld >> Repos - architektonas/commitdiff
Re-added "Fixed Angle" tool. :-)
authorShamus Hammons <jlhamm@acm.org>
Thu, 23 Dec 2021 22:12:20 +0000 (16:12 -0600)
committerShamus Hammons <jlhamm@acm.org>
Thu, 23 Dec 2021 22:12:20 +0000 (16:12 -0600)
src/drawingview.cpp
src/structs.h
src/vector.cpp
src/vector.h

index 8ad55628ced17fd993c289c2c58e524a490ea8b4..2e435d26fe0456a743a8256eef0ded1df12864e0 100644 (file)
@@ -1951,9 +1951,14 @@ void DrawingView::mousePressEvent(QMouseEvent * event)
                        if (Global::fixedLength)
                        {
                                if (dragged->type == OTLine)
-                               {
-                                       dragged->length = Vector::Magnitude(dragged->p[0], dragged->p[1]);
-                               }
+                                       dragged->length = ((Line *)dragged)->Length();
+                       }
+
+                       // Needed for fixed angle handling
+                       if (Global::fixedAngle)
+                       {
+                               if (dragged->type == OTLine)
+                                       dragged->p[2] = ((Line *)dragged)->Unit();
                        }
 
                        if (dragged->type == OTCircle)
@@ -2959,24 +2964,40 @@ void DrawingView::HandleObjectMovement(Point point)
        case OTLine:
                if (obj->hitPoint[0])
                {
+/*
+N.B.: Mixing fixed length with fixed angle (and in this order) is probably *not* going to work out in any meaningful way, and we should probably make the GUI force these to be mutually exclusive.  Besides, this combined effect already works by dragging the line segment by clicking on it.  :-P
+*/
                        if (Global::fixedLength)
                        {
-                               Vector line = point - obj->p[1];
-                               Vector unit = line.Unit();
+                               Vector unit = Vector::Unit(obj->p[1], point);
                                point = obj->p[1] + (unit * obj->length);
                        }
 
+                       if (Global::fixedAngle)
+                       {
+                               // Calculate the component of the current vector along the
+                               // fixed angle: A_compB = (A • Bu) * Bu  (p[2] has the unit
+                               // vector "Bu".)
+                               double magnitudeAlongB = Vector::Dot(Vector(point - obj->p[1]), obj->p[2]);
+                               point = obj->p[1] + (obj->p[2] * magnitudeAlongB);
+                       }
+
                        obj->p[0] = point;
                }
                else if (obj->hitPoint[1])
                {
                        if (Global::fixedLength)
                        {
-                               Vector line = point - obj->p[0];
-                               Vector unit = line.Unit();
+                               Vector unit = Vector::Unit(obj->p[0], point);
                                point = obj->p[0] + (unit * obj->length);
                        }
 
+                       if (Global::fixedAngle)
+                       {
+                               double magnitudeAlongB = Vector::Dot(Vector(point - obj->p[0]), obj->p[2]);
+                               point = obj->p[0] + (obj->p[2] * magnitudeAlongB);
+                       }
+
                        obj->p[1] = point;
                }
                else if (obj->hitObject)
index 62366adaca188179d705dfe97e6c76f4819b1ab6..20a03d264ba0016e3a03835bacf6f7d209750540 100644 (file)
@@ -60,6 +60,9 @@ struct Line {
        Line(Vector pt1, Vector pt2, float th = 1.0, uint32_t c = 0, int l = LSSolid):
                type(OTLine), id(Global::objectID++), layer(0), color(c), thickness(th),
                style(l), selected(false), hovered(false), hitObject(false) { p[0] = pt1; p[1] = pt2; hitPoint[0] = hitPoint[1] = false; }
+       Vector Vect(void) { return Vector(p[0], p[1]); }
+       Vector Unit(void) { return Vector(p[0], p[1]).Unit(); }
+       double Length(void) { return Vector(p[0], p[1]).Magnitude(); }
 };
 
 struct Circle {
index 89b9148a44343b6aa7f3c00bbf8210099731f97f..e62e5800ce5528314f24da40216a65eb8e9b5550 100644 (file)
@@ -223,6 +223,14 @@ bool Vector::isZero(double epsilon/*= 1e-6*/)
        return sqrt((xx * xx) + (yy * yy) + (zz * zz));
 }
 
+//
+// Convenience function
+//
+/*static*/ Vector Vector::Unit(Point p1, Point p2)
+{
+       return Vector(p1, p2).Unit();
+}
+
 //
 // Convenience function
 //
index 67d9aa92f8e0f0d82ebb7bf2fdff4c7febe63277..c3d6a4df89e4d750c42e91f3661ea4739c52d785 100644 (file)
@@ -53,6 +53,7 @@ class Vector
 
                static double Dot(Vector v1, Vector v2);
                static double Magnitude(Vector v1, Vector v2);
+               static Vector Unit(Point p1, Point p2);
                static double Angle(Point p1, Point p2);
                static double Parameter(Vector v1, Vector v2, Vector p);
                static Vector Normal(Vector v1, Vector v2);