- else if (event->buttons() == Qt::NoButton)
- {
- // Moving, not dragging...
- if (tool == TOOLSelect || tool == TOOLDelPt || tool == TOOLAddPt
- || tool == TOOLPolySelect)// || tool == TOOLAddPoly)
- {
- QPoint pt2 = GetAdjustedMousePosition(event);
- 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)));
-
- if (dist < closest)
- closest = dist, ptHighlight = i;
- }
-
- if (ptHighlight != oldPtHighlight)
- {
- oldPtHighlight = ptHighlight;
- 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.
-
- // 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)
- {
- double smallest = 1.0e+99;
-
- for(int i=0; i<pts.GetNumPoints(); i++)
- {
- int32 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);
- double pp = ls.dot(v1) / ls.length(), 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.
-
- if (pp < 0.0)
- dist = v1.length();
- else if (pp > ls.length())
- dist = v2.length();
- else // distance = ?Det?(ls, v1) / |ls|
- dist = fabs((ls.x * v1.y - v1.x * ls.y) / ls.length());
-
-//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:
-//
-//sx sy 1
-//ex ey 1
-//px py 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!]
-//
-//0 0 0
-//(ex - sx) (ey - sy) 0
-//(px - sx) (py - sy) 0
-//
-//which greatly simplifies the calculation of the determinant.