From: Shamus Hammons Date: Thu, 23 Dec 2021 22:12:20 +0000 (-0600) Subject: Re-added "Fixed Angle" tool. :-) X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=architektonas;a=commitdiff_plain;h=92b64dc831492f1d6311a8baece66408f7659f67 Re-added "Fixed Angle" tool. :-) --- diff --git a/src/drawingview.cpp b/src/drawingview.cpp index 8ad5562..2e435d2 100644 --- a/src/drawingview.cpp +++ b/src/drawingview.cpp @@ -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) diff --git a/src/structs.h b/src/structs.h index 62366ad..20a03d2 100644 --- a/src/structs.h +++ b/src/structs.h @@ -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 { diff --git a/src/vector.cpp b/src/vector.cpp index 89b9148..e62e580 100644 --- a/src/vector.cpp +++ b/src/vector.cpp @@ -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 // diff --git a/src/vector.h b/src/vector.h index 67d9aa9..c3d6a4d 100644 --- a/src/vector.h +++ b/src/vector.h @@ -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);