From: Shamus Hammons Date: Tue, 19 May 2015 15:51:51 +0000 (-0500) Subject: Initial bring-back of line to line intersection detection. X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=architektonas;a=commitdiff_plain;h=4a979ddae8aa6b3556f24e8b961f7787c4b40cbe Initial bring-back of line to line intersection detection. --- diff --git a/src/drawingview.cpp b/src/drawingview.cpp index fff56da..8c581bf 100644 --- a/src/drawingview.cpp +++ b/src/drawingview.cpp @@ -689,7 +689,7 @@ void DrawingView::ToolDraw(Painter * painter) { if (toolPoint[0] == toolPoint[1]) return; - + painter->DrawLine(toolPoint[0], toolPoint[1]); // Likely we need a tool container for this... (now we do!) #if 0 @@ -704,7 +704,6 @@ void DrawingView::ToolDraw(Painter * painter) #endif double absAngle = (Vector(toolPoint[1] - toolPoint[0]).Angle()) * RADIANS_TO_DEGREES; - QString text = QChar(0x2221) + QObject::tr(": %1"); informativeText = text.arg(absAngle); @@ -723,7 +722,9 @@ void DrawingView::ToolDraw(Painter * painter) if (toolPoint[0] == toolPoint[1]) return; - painter->DrawLine(toolPoint[0], toolPoint[1]); + Point mirrorPoint = toolPoint[0] + Vector(toolPoint[1], toolPoint[0]); +// painter->DrawLine(toolPoint[0], toolPoint[1]); + painter->DrawLine(mirrorPoint, toolPoint[1]); // Likely we need a tool container for this... (now we do!) #if 0 if (ctrlDown) @@ -738,6 +739,9 @@ void DrawingView::ToolDraw(Painter * painter) double absAngle = (Vector(toolPoint[1] - toolPoint[0]).Angle()) * RADIANS_TO_DEGREES; + if (absAngle > 180.0) + absAngle -= 180.0; + QString text = QChar(0x2221) + QObject::tr(": %1"); informativeText = text.arg(absAngle); @@ -1045,10 +1049,7 @@ void DrawingView::MirrorHandler(int mode, Point p) if (obj.type == OTArc) { -#if 0 - // This is WRONG for mirroring... - obj2->angle[0] = obj.angle[0] + angle; -#endif + // This is 2*mirror angle - obj angle - obj span obj2->angle[0] = (2.0 * angle) - obj.angle[0] - obj.angle[1]; if (obj2->angle[0] > PI_TIMES_2) @@ -1215,6 +1216,21 @@ void DrawingView::mouseMoveEvent(QMouseEvent * event) // Do object hit testing... bool needUpdate = HitTestObjects(point); + // Check for multi-hover... + if (numHovered > 1) + { + GetHovered(hover); + + double t, u; + int numIntersecting = Geometry::Intersects((Object *)hover[0], (Object *)hover[1], &t, &u); + + if (numIntersecting > 0) + { + QString text = tr("Intersection t=%1, u=%2"); + informativeText = text.arg(t).arg(u); + } + } + // Do tool handling, if any are active... if (Global::tool) { diff --git a/src/geometry.cpp b/src/geometry.cpp index e0ad270..11e633f 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -15,12 +15,12 @@ #include "geometry.h" #include -#include "circle.h" -#include "dimension.h" -#include "line.h" +#include #include "mathconstants.h" +// This is unused +#if 0 Point Geometry::IntersectionOfLineAndLine(Point p1, Point p2, Point p3, Point p4) { // Find the intersection of the lines by formula: @@ -42,6 +42,7 @@ Point Geometry::IntersectionOfLineAndLine(Point p1, Point p2, Point p3, Point p4 return Point(px / d, py / d, 0); } +#endif // Returns the parameter of a point in space to this vector. If the parameter @@ -104,6 +105,15 @@ double Geometry::Determinant(Point p1, Point p2) } +int Geometry::Intersects(Object * obj1, Object * obj2, double * tp/*= 0*/, double * up/*= 0*/, double * vp/*= 0*/, double * wp/*= 0*/) +{ + if ((obj1->type == OTLine) && (obj2->type == OTLine)) + return CheckLineToLineIntersection(obj1, obj2, tp, up); + + return 0; +} + + /* Intersecting line segments: An easier way: @@ -123,22 +133,16 @@ So check if the above two numbers are both >=0 and <=1. */ -#if 0 -// Finds the intesection between two objects (if any) -bool Geometry::Intersects(Object * obj1, Object * obj2, double * t, double * s) -{ -} -#endif - -#if 0 // Finds the intersection between two lines (if any) -int Geometry::Intersects(Line * l1, Line * l2, double * tp/*= 0*/, double * up/*= 0*/) +int Geometry::CheckLineToLineIntersection(Object * l1, Object * l2, double * tp, double * up) { - Vector r(l1->position, l1->endpoint); - Vector s(l2->position, l2->endpoint); - Vector v1 = l2->position - l1->position; // q - p -// Vector v2 = l1->position - l2->position; // p - q -//printf("l1: (%lf, %lf) (%lf, %lf), l2: (%lf, %lf) (%lf, %lf)\n", l1->position.x, l1->position.y, l1->endpoint.x, l1->endpoint.y, l2->position.x, l2->position.y, l2->endpoint.x, l2->endpoint.y); + Vector r(l1->p[0], l1->p[1]); + Vector s(l2->p[0], l2->p[1]); + Vector v1 = l2->p[0] - l1->p[0]; // q - p +#if 0 + Vector v2 = l1->p[0] - l2->p[0]; // p - q +printf("l1: (%lf, %lf) (%lf, %lf), l2: (%lf, %lf) (%lf, %lf)\n", l1->p[0].x, l1->p[0].y, l1->p[1].x, l1->p[1].y, l2->p[0].x, l2->p[0].y, l2->p[1].x, l2->p[1].y); +#endif double rxs = (r.x * s.y) - (s.x * r.y); double t, u; @@ -146,10 +150,12 @@ int Geometry::Intersects(Line * l1, Line * l2, double * tp/*= 0*/, double * up/* { double qpxr = (v1.x * r.y) - (r.x * v1.y); -//printf(" --> R x S = 0! (q - p) x r = %lf\n", qpxr); -//printf(" -->(q - p) . r = %lf, r . r = %lf\n", v1.Dot(r), r.Dot(r)); -//printf(" -->(p - q) . s = %lf, s . s = %lf\n", v2.Dot(s), s.Dot(s)); -//printf(" -->(q - p) . s = %lf, (p - q) . r = %lf\n", v1.Dot(s), v2.Dot(r)); +#if 0 +printf(" --> R x S = 0! (q - p) x r = %lf\n", qpxr); +printf(" -->(q - p) . r = %lf, r . r = %lf\n", v1.Dot(r), r.Dot(r)); +printf(" -->(p - q) . s = %lf, s . s = %lf\n", v2.Dot(s), s.Dot(s)); +printf(" -->(q - p) . s = %lf, (p - q) . r = %lf\n", v1.Dot(s), v2.Dot(r)); +#endif // Lines are parallel, so no intersection... if (qpxr != 0) @@ -168,13 +174,13 @@ int Geometry::Intersects(Line * l1, Line * l2, double * tp/*= 0*/, double * up/* return 0; #else // Check to see which endpoints are connected... Four possibilities: - if (l1->position == l2->position) + if (l1->p[0] == l2->p[0]) t = 0, u = 0; - else if (l1->position == l2->endpoint) + else if (l1->p[0] == l2->p[1]) t = 0, u = 1.0; - else if (l1->endpoint == l2->position) + else if (l1->p[1] == l2->p[0]) t = 1.0, u = 0; - else if (l1->endpoint == l2->endpoint) + else if (l1->p[1] == l2->p[1]) t = 1.0, u = 1.0; else return 0; @@ -213,6 +219,7 @@ Now there are five cases (NOTE: only valid if vectors face the same way!): } +#if 0 // Finds the intersection between two lines (if any) int Geometry::Intersects(Line * l1, Dimension * d1, double * tp/*= 0*/, double * up/*= 0*/) { diff --git a/src/geometry.h b/src/geometry.h index 2776ae3..865dc6d 100644 --- a/src/geometry.h +++ b/src/geometry.h @@ -1,21 +1,20 @@ #ifndef __GEOMETRY_H__ #define __GEOMETRY_H__ +#include "structs.h" #include "vector.h" -//class Circle; -//class Dimension; -//class Line; - class Geometry { public: // All methods are class methods for this class - static Point IntersectionOfLineAndLine(Point, Point, Point, Point); +//unused static Point IntersectionOfLineAndLine(Point, Point, Point, Point); static double ParameterOfLineAndPoint(Point, Point, Point); static Point MirrorPointAroundLine(Point, Point, Point); static Point RotatePointAroundPoint(Point, Point, double); static double Determinant(Point, Point); + static int Intersects(Object *, Object *, double * tp = 0, double * up = 0, double * vp = 0, double * wp = 0); + static int CheckLineToLineIntersection(Object *, Object *, double *, double *); // static int Intersects(Line *, Line *, double * tp = 0, double * up = 0); // static int Intersects(Line *, Dimension *, double * tp = 0, double * up = 0); // static int Intersects(Line * l, Circle * c, double * tp = 0, double * up = 0, double * vp = 0, double * wp = 0); diff --git a/src/mirroraction.cpp b/src/mirroraction.cpp deleted file mode 100644 index 8770173..0000000 --- a/src/mirroraction.cpp +++ /dev/null @@ -1,161 +0,0 @@ -// mirroraction.cpp: Action class for mirroring selected objects -// -// Part of the Architektonas Project -// (C) 2011 Underground Software -// See the README and GPLv3 files for licensing and warranty information -// -// JLH = James Hammons -// -// WHO WHEN WHAT -// --- ---------- ------------------------------------------------------------ -// JLH 08/27/2011 Created this file -// - -#include "mirroraction.h" -#include "applicationwindow.h" -#include "container.h" -#include "drawingview.h" -#include "line.h" -#include "mathconstants.h" -#include "painter.h" - - -enum { FIRST_POINT, NEXT_POINT }; - - -MirrorAction::MirrorAction(): state(FIRST_POINT), line(NULL), - shiftWasPressedOnNextPoint(false), ctrlWasPressed(false), - mirror(new Container(Vector())) -{ - ApplicationWindow::drawing->document.CopySelectedContentsTo(mirror); - mirror->Save(); -} - - -MirrorAction::~MirrorAction() -{ -} - - -/*virtual*/ void MirrorAction::Draw(Painter * painter) -{ - painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine)); - - if (state == FIRST_POINT) - { - painter->DrawHandle(p1); - } - else - { - Vector reflectedP2 = -(p2 - p1); - Point newP2 = p1 + reflectedP2; - painter->DrawLine(newP2, p2); - painter->DrawHandle(p1); - - double absAngle = (Vector(p2 - p1).Angle()) * RADIANS_TO_DEGREES; - - // 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); - - if (ctrlWasPressed) - text += " (Copy)"; - - painter->DrawInformativeText(text); - - // Draw the mirror only if there's been a line to mirror around - if (p1 != p2) - mirror->Draw(painter); - } -} - - -/*virtual*/ void MirrorAction::MouseDown(Vector point) -{ - // Clear our override... - shiftWasPressedOnNextPoint = false; - - if (state == FIRST_POINT) - p1 = point; - else - p2 = point; -} - - -/*virtual*/ void MirrorAction::MouseMoved(Vector point) -{ - if (state == FIRST_POINT) - p1 = point; - else - { - p2 = point; - mirror->Restore(); - mirror->Mirror(p1, p2); - } -} - - -/*virtual*/ void MirrorAction::MouseReleased(void) -{ - if (state == FIRST_POINT) - { - p2 = p1; - state = NEXT_POINT; - } - else if (state == NEXT_POINT) - { - if (!ctrlWasPressed) - { - state = FIRST_POINT; - ApplicationWindow::drawing->document.MirrorSelected(p1, p2); - - mirror->Clear(); - ApplicationWindow::drawing->document.CopySelectedContentsTo(mirror); - mirror->Save(); - } - else - { - mirror->CopyContentsTo(&(ApplicationWindow::drawing->document)); - } - } -} - - -/*virtual*/ void MirrorAction::KeyDown(int key) -{ - if ((key == Qt::Key_Shift) && (state == NEXT_POINT)) - { - shiftWasPressedOnNextPoint = true; - p1Save = p1; - p1 = p2; - state = FIRST_POINT; - emit(NeedRefresh()); - } - else if (key == Qt::Key_Control) - { - ctrlWasPressed = true; - emit(NeedRefresh()); - } -} - - -/*virtual*/ void MirrorAction::KeyReleased(int key) -{ - if ((key == Qt::Key_Shift) && shiftWasPressedOnNextPoint) - { - shiftWasPressedOnNextPoint = false; - p2 = p1; - p1 = p1Save; - state = NEXT_POINT; - emit(NeedRefresh()); - } - else if (key == Qt::Key_Control) - { - ctrlWasPressed = false; - emit(NeedRefresh()); - } -} - diff --git a/src/mirroraction.h b/src/mirroraction.h deleted file mode 100644 index aad3586..0000000 --- a/src/mirroraction.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __MIRRORACTION_H__ -#define __MIRRORACTION_H__ - -#include "action.h" - -class Container; -class Line; - -class MirrorAction: public Action -{ - public: - MirrorAction(); - ~MirrorAction(); - - virtual void Draw(Painter *); - virtual void MouseDown(Vector); - virtual void MouseMoved(Vector); - virtual void MouseReleased(void); - virtual void KeyDown(int); - virtual void KeyReleased(int); - - private: - int state; - Line * line; - Vector p1, p2, p1Save; - bool shiftWasPressedOnNextPoint; - bool ctrlWasPressed; - Container * mirror; -}; - -#endif // __MIRRORACTION_H__ -