// JLH = James L. Hammons <jlhamm@acm.org>
//
// Who When What
-// --- ---------- -------------------------------------------------------------
+// --- ---------- -----------------------------------------------------------
// JLH 08/28/2008 Created this file
// JLH 09/02/2008 Separated scrolling from dedicated tool to MMB drag
// JLH 03/13/2009 Converted from wxWidgets to Qt
#include "editwindow.h"
#include "charwindow.h"
#include "debug.h"
-#include "graphicprimitives.h"
+#include "global.h"
#include "mainwindow.h"
#include "ttedit.h"
#include "vector.h"
EditWindow::EditWindow(QWidget * parent/*= NULL*/): QWidget(parent),
scale(1.0), offsetX(-10), offsetY(-10), tool(TOOLSelect),
ptHighlight(-1), oldPtHighlight(-1), ptNextHighlight(-1), oldPtNextHighlight(-1),
- polyFirstPoint(true), showRotationCenter(false), haveZeroPoint(false)
+ polyFirstPoint(true), showRotationCenter(false), haveZeroPoint(false),
+ selectionInProgress(false)
{
setBackgroundRole(QPalette::Base);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
CreateCursors();
setCursor(cur[TOOLSelect]);
setMouseTracking(true);
+ ClearSelection();
}
void EditWindow::CreateCursors(void)
{
- int hotx[11] = { 1, 1, 11, 15, 1, 1, 1, 1, 1, 1, 1 };
- int hoty[11] = { 1, 1, 11, 13, 1, 1, 1, 1, 1, 1, 1 };
- char cursorName[11][48] = { "select", "select-poly", "scroll", "zoom", "add-point",
- "add-poly", "del-point", "del-poly", "rotate", "rotate", "select" };
+ int hotx[12] = { 1, 1, 1, 15, 1, 1, 1, 1, 1, 1, 1, 11 };
+ int hoty[12] = { 1, 1, 1, 13, 1, 1, 1, 1, 1, 1, 1, 11 };
+ char cursorName[12][48] = { "select", "select-poly", "select-multi", "zoom",
+ "add-point", "add-poly", "del-point", "del-poly", "rotate", "rotate",
+ "select", "scroll" };
- for(int i=0; i<11; i++)
+ for(int i=0; i<12; i++)
{
QString s;
s.sprintf(":/res/cursor-%s.png", cursorName[i]);
QPoint EditWindow::GetAdjustedMousePosition(QMouseEvent * event)
{
- QSize winSize = size();
- // This is undoing the transform, e.g. going from client coords to local coords.
- // In essence, the height - y is height + (y * -1), the (y * -1) term doing the
- // conversion of the y-axis from increasing bottom to top.
- return QPoint(offsetX + event->x(), offsetY + (winSize.height() - event->y()));
+ // This is undoing the transform, e.g. going from client coords to local
+ // coords. In essence, the height - y is height + (y * -1), the (y * -1)
+ // term doing the conversion of the y-axis from increasing bottom to top.
+ return QPoint(offsetX + event->x(), offsetY + (size().height() - event->y()));
}
QPoint EditWindow::GetAdjustedClientPosition(int x, int y)
{
- QSize winSize = size();
-
// VOODOO ALERT (ON Y COMPONENT!!!!)
- return QPoint(-offsetX + x, (winSize.height() - (-offsetY + y)) * +1.0);
+ return QPoint(-offsetX + x, (size().height() - (-offsetY + y)) * +1.0);
}
*/
void EditWindow::paintEvent(QPaintEvent * /*event*/)
{
- QPainter p(this);
+ QPainter qtp(this);
+ Painter painter(&qtp);
//hm, causes lockup (or does it???)
- p.setRenderHint(QPainter::Antialiasing);
-
- QSize winSize = size();
-
- p.translate(QPoint(-offsetX, winSize.height() - (-offsetY)));
- p.scale(1.0, -1.0);
+//& it doesn't help with our Bezier rendering code :-P
+ painter.SetRenderHint(QPainter::Antialiasing);
+
+ Global::zoom = scale;
+ Global::origin = Vector(offsetX, offsetY);
+ Global::viewportHeight = size().height();
+ Global::screenSize = Vector(size().width(), size().height());
+// p.translate(QPoint(-offsetX, size().height() - (-offsetY)));
+// p.scale(1.0, -1.0);
+//Nope, a big load of shit. So we'll have to bite the bullet and do it the
+//hard way™.
+// p.scale(scale, -scale);
// Scrolling can be done by using OffsetViewportOrgEx
// Scaling can be done by adjusting SetWindowExtEx (it's denominator of txform)
// Instead, we have to scale EVERYTHING by hand. Crap!
// It's not *that* bad, but not as convenient either...
- p.setPen(QPen(Qt::blue, 1.0, Qt::DotLine));
+ painter.SetPen(QPen(Qt::blue, 1.0, Qt::DotLine));
// Draw coordinate axes
- p.drawLine(0, -16384, 0, 16384);
- p.drawLine(-16384, 0, 16384, 0);
+ painter.DrawLine(0, -16384, 0, 16384);
+ painter.DrawLine(-16384, 0, 16384, 0);
// Draw rotation center (if active)
if (showRotationCenter)
{
- p.setPen(QPen(Qt::red, 2.0, Qt::SolidLine));
- p.drawLine(rotationCenter.x() + 7, rotationCenter.y(), rotationCenter.x() - 7, rotationCenter.y());
- p.drawLine(rotationCenter.x(), rotationCenter.y() + 7, rotationCenter.x(), rotationCenter.y() - 7);
+ painter.SetPen(QPen(Qt::red, 2.0, Qt::SolidLine));
+ painter.DrawLine(rotationCenter.x + 7, rotationCenter.y, rotationCenter.x - 7, rotationCenter.y);
+ painter.DrawLine(rotationCenter.x, rotationCenter.y + 7, rotationCenter.x, rotationCenter.y - 7);
}
// Draw points
for(int i=0; i<pts.GetNumPoints(); i++)
{
- if (i == ptHighlight)
+ /*if (tool == TOOLMultiSelect)
{
- p.setPen(QPen(Qt::red, 1.0, Qt::SolidLine));
+ if (selectedPoints[i])
+ {
+ qtp.setPen(QPen(Qt::red, 1.0, Qt::SolidLine));
+ }
+ else
+ {
+ qtp.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
+ }
+ }
+ else*/
+ if (((i == ptHighlight) && (tool != TOOLMultiSelect)) || ((tool == TOOLMultiSelect) && selectedPoints[i]))
+ {
+ painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
if (pts.GetOnCurve(i))
{
- DrawSquareDotN(p, pts.GetX(i), pts.GetY(i), 7);
- DrawSquareDotN(p, pts.GetX(i), pts.GetY(i), 9);
+ painter.DrawSquareDotN(pts.GetXY(i), 7);
+ painter.DrawSquareDotN(pts.GetXY(i), 9);
}
else
{
- DrawRoundDotN(p, pts.GetX(i), pts.GetY(i), 7);
- DrawRoundDotN(p, pts.GetX(i), pts.GetY(i), 9);
+ painter.DrawRoundDotN(pts.GetXY(i), 7);
+ painter.DrawRoundDotN(pts.GetXY(i), 9);
}
}
else if ((i == ptHighlight || i == ptNextHighlight) && tool == TOOLAddPt)
{
- p.setPen(QPen(Qt::green, 1.0, Qt::SolidLine));
+ painter.SetPen(QPen(Qt::green, 1.0, Qt::SolidLine));
if (pts.GetOnCurve(i))
{
- DrawSquareDotN(p, pts.GetX(i), pts.GetY(i), 7);
- DrawSquareDotN(p, pts.GetX(i), pts.GetY(i), 9);
+ painter.DrawSquareDotN(pts.GetXY(i), 7);
+ painter.DrawSquareDotN(pts.GetXY(i), 9);
}
else
{
- DrawRoundDotN(p, pts.GetX(i), pts.GetY(i), 7);
- DrawRoundDotN(p, pts.GetX(i), pts.GetY(i), 9);
+ painter.DrawRoundDotN(pts.GetXY(i), 7);
+ painter.DrawRoundDotN(pts.GetXY(i), 9);
}
}
else
{
- p.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
+ painter.SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
+#if 1
if (pts.GetOnCurve(i))
- DrawSquareDot(p, pts.GetX(i), pts.GetY(i));
+ painter.DrawSquareDot(pts.GetXY(i));
else
- DrawRoundDot(p, pts.GetX(i), pts.GetY(i));
+ painter.DrawRoundDot(pts.GetXY(i));
+#else
+ (pts.GetOnCurve(i) ? DrawSquareDot(p, pts.GetX(i), pts.GetY(i))
+ : DrawRoundDot(p, pts.GetX(i), pts.GetY(i)));
+#endif
}
if (tool == TOOLDelPt && i == ptHighlight)
{
- p.setPen(QPen(Qt::red, 1.0, Qt::SolidLine));
- p.drawLine(pts.GetX(i) - 5, pts.GetY(i) - 5, pts.GetX(i) + 5, pts.GetY(i) + 5);
- p.drawLine(pts.GetX(i) + 5, pts.GetY(i) - 5, pts.GetX(i) - 5, pts.GetY(i) + 5);
+ painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
+ painter.DrawLine(pts.GetX(i) - 5, pts.GetY(i) - 5, pts.GetX(i) + 5, pts.GetY(i) + 5);
+ painter.DrawLine(pts.GetX(i) + 5, pts.GetY(i) - 5, pts.GetX(i) - 5, pts.GetY(i) + 5);
}
}
// Draw curve formed by points
- p.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
- DrawGlyph(p, pts);
+ painter.SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
+ DrawGlyph(painter, pts);
if (haveZeroPoint)
{
GlyphPoints rotated = pts;
if (tool == TOOLRotate)
- rotated.RotatePoints(rotationAngle, IPoint(rotationCenter.x(), rotationCenter.y()));
+ rotated.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y));
else if (tool == TOOLRotatePoly)
{
uint16_t poly = rotated.GetPolyForPointNumber(ptHighlight);
rotated.RotatePolyAroundCentroid(poly, rotationAngle);
}
- p.setPen(QPen(QColor(255, 0, 255), 1.0, Qt::SolidLine));
- DrawGlyph(p, rotated);
+ painter.SetPen(QPen(QColor(255, 0, 255), 1.0, Qt::SolidLine));
+ DrawGlyph(painter, rotated);
+ }
+
+ if (selectionInProgress)
+ {
+ painter.SetPen(QPen(QColor(255, 127, 0, 255)));
+ painter.SetBrush(QBrush(QColor(255, 127, 0, 100)));
+ painter.DrawRect(selection);
}
}
-void EditWindow::DrawGlyph(QPainter & p, GlyphPoints & glyph)
+void EditWindow::DrawGlyph(Painter & p, GlyphPoints & glyph)
{
for(int poly=0; poly<glyph.GetNumPolys(); poly++)
{
}
-void EditWindow::DrawGlyphPoly(QPainter & p, GlyphPoints & glyph, uint16_t poly)
+void EditWindow::DrawGlyphPoly(Painter & p, GlyphPoints & glyph, uint16_t poly)
{
// Sanity check
if (glyph.GetNumPoints(poly) < 3)
if (glyph.GetOnCurve(poly, i) && glyph.GetNextOnCurve(poly, i))
{
IPoint pt2 = glyph.GetNextPoint(poly, i);
- p.drawLine(pt.x, pt.y, pt2.x, pt2.y);
+ p.DrawLine(pt.x, pt.y, pt2.x, pt2.y);
pt = pt2;
}
else
if (glyph.GetOnCurve(poly, i))
continue;
- // We are now guaranteed that we are sitting on a curve control point
- // (off curve). Figure the extent of the curve: If the following is a
- // curve control point, then use the midpoint to it otherwise go to
- // the next point since it's on curve.
+ // We are now guaranteed that we are sitting on a curve control
+ // point (off curve). Figure the extent of the curve: If the
+ // following is a curve control point, then use the midpoint to it
+ // otherwise go to the next point since it's on curve.
IPoint pt2 = (glyph.GetNextOnCurve(poly, i)
? glyph.GetNextPoint(poly, i) : glyph.GetMidpointToNext(poly, i));
- Bezier(p, pt, glyph.GetPoint(poly, i), pt2);
+ p.DrawBezier(pt, glyph.GetPoint(poly, i), pt2);
pt = pt2;
}
}
}
+void EditWindow::ClearSelection(void)
+{
+ for(int i=0; i<65536; i++)
+ selectedPoints[i] = false;
+}
+
+
void EditWindow::mousePressEvent(QMouseEvent * event)
{
if (event->button() == Qt::RightButton)
}
else if (event->button() == Qt::MidButton)
{
- setCursor(cur[2]); // Scrolling cursor
+ // Scrolling cursor
+ setCursor(cur[11]);
+ ptPrevious = Vector(event->x(), event->y());
+ ptPrevious /= Global::zoom;
}
else if (event->button() == Qt::LeftButton)
{
if (tool == TOOLScroll || tool == TOOLZoom)
;//meh CaptureMouse(); // Make sure we capture the mouse when in scroll/zoom mode
+ else if (tool == TOOLMultiSelect)
+ {
+// QPoint pt = GetAdjustedMousePosition(event);
+ Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+ selectionInProgress = true;
+ selection.setTopLeft(QPoint(pt.x, pt.y));
+ selection.setBottomRight(QPoint(pt.x, pt.y));
+ }
else if (tool == TOOLAddPt) // "Add Point" tool
{
- QPoint pt = GetAdjustedMousePosition(event);
- IPoint pointToAdd(pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
+// QPoint pt = GetAdjustedMousePosition(event);
+ Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+ IPoint pointToAdd(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
if (pts.GetNumPoints() < 2)
{
pts.AddNewPolyAtEnd();
}
- QPoint pt = GetAdjustedMousePosition(event);
+// QPoint pt = GetAdjustedMousePosition(event);
+ Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
//printf("GetAdjustedMousePosition = %i, %i\n", pt.x(), pt.y());
// Append a point to the end of the structure
- pts += IPoint(pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
+ pts += IPoint(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
ptHighlight = pts.GetNumPoints() - 1;
update();
#ifdef DEBUGFOO
{
if (pts.GetNumPoints() > 0)
{
- pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
+// pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
+ Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
//printf("GetAdjustedClientPosition = %i, %i\n", pt.x(), pt.y());
// WarpPointer(pt.x, pt.y);
- QCursor::setPos(mapToGlobal(pt));
+ QPoint warp(pt.x, pt.y);
+ QCursor::setPos(mapToGlobal(warp));
if (event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier)
{
// paint the rotation center, then use the 1st mouse move event to establish
// the rotation "zero line", which becomes the line of reference to all
// subsequent mouse moves.
- rotationCenter = GetAdjustedMousePosition(event);
+// rotationCenter = GetAdjustedMousePosition(event);
+ rotationCenter = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
showRotationCenter = true;
haveZeroPoint = false;
rotationAngle = 0;
else if (tool == TOOLRotatePoly)
{
IPoint centroid = pts.GetPolyCentroid(pts.GetPolyForPointNumber(ptHighlight));
- rotationCenter = QPoint(centroid.x, centroid.y);
+ rotationCenter = Vector(centroid.x, centroid.y);
showRotationCenter = true;
- pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
- QCursor::setPos(mapToGlobal(pt));
- rotationZeroPoint = QPoint(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
+// pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
+ Vector pt = Painter::QtToCartesianCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
+ QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
+ rotationZeroPoint = Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
haveZeroPoint = true;
rotationAngle = 0;
update();
else if (tool == TOOLFlipWinding)
{
pts.InvertPolyDrawSequence(pts.GetPolyForPointNumber(ptHighlight));
- pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
- QCursor::setPos(mapToGlobal(pt));
+// pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
+ Vector pt = Painter::QtToCartesianCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
+ QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
update();
}
}
else if (event->buttons() == Qt::MidButton)
{
// Calc offset from previous point
- pt = event->pos();
- ptOffset = QPoint(pt.x() - ptPrevious.x(), pt.y() - ptPrevious.y());
+ Vector pt(event->x(), event->y());
+ pt /= Global::zoom;
+ ptOffset = Vector(pt.x - ptPrevious.x, pt.y - ptPrevious.y);
// Then multiply it by the scaling factor. Whee!
// This looks wacky because we're using screen coords for the offset...
// Otherwise, we would subtract both offsets!
- offsetX -= ptOffset.x(), offsetY += ptOffset.y();
+ offsetX -= ptOffset.x, offsetY += ptOffset.y;
update();
ptPrevious = pt;
}
if (tool == TOOLSelect && pts.GetNumPoints() == 0)
return;
- QPoint pt2 = GetAdjustedMousePosition(event);
- pts.SetXY(ptHighlight, pt2.x(), pt2.y());
+// QPoint pt2 = GetAdjustedMousePosition(event);
+ Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+ pts.SetXY(ptHighlight, pt2.x, pt2.y);
update();
}
else if (tool == TOOLPolySelect)
{
if (pts.GetNumPoints() > 0)
{
- QPoint pt2 = GetAdjustedMousePosition(event);
+// QPoint pt2 = GetAdjustedMousePosition(event);
+ Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
// Should also set onCurve here as well, depending on keystate
//Or should we?
//Would be nice, but we'd need to trap the keyPressEvent() as well, otherwise pressing/releasing
//the hotkey would show no change until the user moved their mouse.
- pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x() - pts.GetX(ptHighlight), pt2.y() - pts.GetY(ptHighlight));
+ pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x - pts.GetX(ptHighlight), pt2.y - pts.GetY(ptHighlight));
update();
}
}
{
if (!haveZeroPoint)
{
- rotationZeroPoint = GetAdjustedMousePosition(event);
+// rotationZeroPoint = GetAdjustedMousePosition(event);
+ rotationZeroPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
haveZeroPoint = true;
}
else
{
// Figure out the angle between the "zero" vector and the current one,
// then rotate all points relative to the "zero" vector (done by paint())
- QPoint currentPoint = GetAdjustedMousePosition(event);
- Vector v1(rotationZeroPoint.x(), rotationZeroPoint.y(), 0,
- rotationCenter.x(), rotationCenter.y(), 0);
- Vector v2(currentPoint.x(), currentPoint.y(), 0,
- rotationCenter.x(), rotationCenter.y(), 0);
+// QPoint currentPoint = GetAdjustedMousePosition(event);
+ Vector currentPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+ Vector v1(rotationZeroPoint.x, rotationZeroPoint.y, 0,
+ rotationCenter.x, rotationCenter.y, 0);
+ Vector v2(currentPoint.x, currentPoint.y, 0,
+ rotationCenter.x, rotationCenter.y, 0);
// rotationAngle = v1.Angle(v2);
rotationAngle = v2.Angle(v1);
update();
}
}
+ else if (tool == TOOLMultiSelect)
+ {
+// QPoint pt = GetAdjustedMousePosition(event);
+ Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+ selection.setBottomRight(QPoint(pt.x, pt.y));
+
+ for(int i=0; i<pts.GetNumPoints(); i++)
+ {
+ if (selection.contains(QPoint(pts.GetX(i), pts.GetY(i))))
+ selectedPoints[i] = true;
+ else
+ selectedPoints[i] = false;
+ }
+
+ update();
+ }
}
else if (event->buttons() == Qt::NoButton)
{
if (tool == TOOLSelect || tool == TOOLDelPt || tool == TOOLAddPt
|| tool == TOOLPolySelect || tool == TOOLRotatePoly || tool == TOOLFlipWinding)
{
- QPoint pt2 = GetAdjustedMousePosition(event);
+// QPoint pt2 = GetAdjustedMousePosition(event);
+ Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
double closest = 1.0e+99;
for(int i=0; i<pts.GetNumPoints(); i++)
{
- double dist = ((pt2.x() - pts.GetX(i)) * (pt2.x() - pts.GetX(i)))
- + ((pt2.y() - pts.GetY(i)) * (pt2.y() - pts.GetY(i)));
+ double dist = ((pt2.x - pts.GetX(i)) * (pt2.x - pts.GetX(i)))
+ + ((pt2.y - pts.GetY(i)) * (pt2.y - pts.GetY(i)));
if (dist < closest)
closest = dist, ptHighlight = i;
update();
}
- // What follows here looks like voodoo, but is really simple. What we do is
- // check to see if the mouse point has a perpendicular intersection with any of
- // the line segments. If it does, calculate the length of the perpendicular
- // and choose the smallest length. If there is no perpendicular, then choose the
- // length of line connecting the closer of either the first endpoint or the
- // second and choose the smallest of those.
+ // What follows here looks like voodoo, but is really simple. What
+ // we do is check to see if the mouse point has a perpendicular
+ // intersection with any of the line segments. If it does,
+ // calculate the length of the perpendicular and choose the
+ // smallest length. If there is no perpendicular, then choose the
+ // length of line connecting the closer of either the first
+ // endpoint or the second and choose the smallest of those.
- // There is one bit of math that looks like voodoo to me ATM--will explain once
- // I understand it better (the calculation of the length of the perpendicular).
+ // There is one bit of math that looks like voodoo to me ATM--will
+ // explain once I understand it better (the calculation of the
+ // length of the perpendicular).
if (pts.GetNumPoints() > 1 && tool == TOOLAddPt)
{
int32_t p1x = pts.GetX(i), p1y = pts.GetY(i),
p2x = pts.GetX(pts.GetNext(i)), p2y = pts.GetY(pts.GetNext(i));
- Vector ls(p2x, p2y, 0, p1x, p1y, 0), v1(pt2.x(), pt2.y(), 0, p1x, p1y, 0),
- v2(pt2.x(), pt2.y(), 0, p2x, p2y, 0);
+ Vector ls(p2x, p2y, 0, p1x, p1y, 0),
+ v1(pt2.x, pt2.y, 0, p1x, p1y, 0),
+ v2(pt2.x, pt2.y, 0, p2x, p2y, 0);
double pp = ls.Dot(v1) / ls.Magnitude(), dist;
// Geometric interpretation:
-// pp is the paremeterized point on the vector ls where the perpendicular intersects ls.
-// If pp < 0, then the perpendicular lies beyond the 1st endpoint. If pp > length of ls,
-// then the perpendicular lies beyond the 2nd endpoint.
+// pp is the paremeterized point on the vector ls where the perpendicular
+// intersects ls. If pp < 0, then the perpendicular lies beyond the 1st
+// endpoint. If pp > length of ls, then the perpendicular lies beyond the 2nd
+// endpoint.
if (pp < 0.0)
dist = v1.Magnitude();
//The answer to the above looks like it might be found here:
//
-//If the segment endpoints are s and e, and the point is p, then the test for the perpendicular
-//intercepting the segment is equivalent to insisting that the two dot products {s-e}.{s-p} and
-//{e-s}.{e-p} are both non-negative. Perpendicular distance from the point to the segment is
-//computed by first computing the area of the triangle the three points form, then dividing by the
-//length of the segment. Distances are done just by the Pythagorean theorem. Twice the area of the
-//triangle formed by three points is the determinant of the following matrix:
+//If the segment endpoints are s and e, and the point is p, then the test for
+//the perpendicular intercepting the segment is equivalent to insisting that
+//the two dot products {s-e}.{s-p} and {e-s}.{e-p} are both non-negative.
+//Perpendicular distance from the point to the segment is computed by first
+//computing the area of the triangle the three points form, then dividing by
+//the length of the segment. Distances are done just by the Pythagorean
+//theorem. Twice the area of the triangle formed by three points is the
+//determinant of the following matrix:
//
//sx sy 1
//ex ey 1
//
//By translating the start point to the origin, this can be rewritten as:
//By subtracting row 1 from all rows, you get the following:
-//[because sx = sy = 0. you could leave out the -sx/y terms below. because we subtracted
-// row 1 from all rows (including row 1) row 1 turns out to be zero. duh!]
+//[because sx = sy = 0. you could leave out the -sx/y terms below. because we
+//subtracted row 1 from all rows (including row 1) row 1 turns out to be zero.
+//duh!]
//
//0 0 0
//(ex - sx) (ey - sy) 0
}
}
- ptPrevious = event->pos();
+ ptPrevious = Vector(event->x(), event->y());
}
event->accept();
haveZeroPoint = false;
if (tool == TOOLRotate)
- pts.RotatePoints(rotationAngle, IPoint(rotationCenter.x(), rotationCenter.y()));
+ pts.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y));
else
{
uint16_t poly = pts.GetPolyForPointNumber(ptHighlight);
((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts);
((TTEdit *)qApp)->charWnd->update();
+ if (tool == TOOLMultiSelect)
+ {
+ selectionInProgress = false;
+ update();
+ }
}
event->accept();