X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdrawingview.cpp;fp=src%2Fdrawingview.cpp;h=e65bbe92de99f12d47f6f2e12596c25d33485c1d;hb=10cf4c797bed05831e976068b7504908279dc997;hp=39196a753646a9eb7929e8d699b9e21f89c8fce3;hpb=3c890e51a9763ffcee49e15753453a7da248272b;p=architektonas diff --git a/src/drawingview.cpp b/src/drawingview.cpp index 39196a7..e65bbe9 100644 --- a/src/drawingview.cpp +++ b/src/drawingview.cpp @@ -459,31 +459,18 @@ void DrawingView::RenderObjects(Painter * painter, VPVector & v, int layer, bool { painter->SetBrush(QBrush(Qt::NoBrush)); Polyline * pl = (Polyline *)obj; - Point lastp; - double lastbump; - for(VPVectorIter i=pl->points.begin(); i!=pl->points.end(); i++) + for(long unsigned int i=0; i<(pl->points.size()-1); i++) { - if (i != pl->points.begin()) - { - Point p = ((Object *)(*i))->p[0]; - double bump = ((Object *)(*i))->length; - - if (lastbump == 0) - painter->DrawLine(lastp, p); - else - { - Arc a = Geometry::Unpack(lastp, p, lastbump); - painter->DrawArc(a.p[0], a.radius[0], a.angle[0], a.angle[1]); - } + Point p1 = pl->points[i]; + Point p2 = pl->points[i + 1]; - lastp = p; - lastbump = bump; - } + if (p1.b == 0) + painter->DrawLine(p1, p2); else { - lastp = ((Object *)(*i))->p[0]; - lastbump = ((Object *)(*i))->length; + Arc a = Geometry::Unpack(p1, p2, p1.b); + painter->DrawArc(a.p[0], a.radius[0], a.angle[0], a.angle[1]); } } @@ -2397,6 +2384,7 @@ Point DrawingView::SnapPointToGrid(Point point) point.y = floor(point.y); point.z = 0; // Make *sure* Z doesn't go anywhere!!! point *= Global::gridSpacing; + return point; } @@ -2441,68 +2429,14 @@ Rect DrawingView::GetObjectExtents(Object * obj) case OTArc: { Arc * a = (Arc *)obj; + rect = a->Bounds(); + break; + } - double start = a->angle[0]; - double end = start + a->angle[1]; - - // Swap 'em if the span is negative... - if (a->angle[1] < 0) - { - end = a->angle[0]; - start = end + a->angle[1]; - } - - rect = Rect(Point(cos(start), sin(start)), Point(cos(end), sin(end))); - - // If the end of the arc is before the beginning, add 360 degrees to it - if (end < start) - end += TAU; - -/* -Find which quadrant the start angle is in (consider the beginning of the 90° angle to be in the quadrant, the end to be in the next quadrant). Then, divide the span into 90° segments. The integer portion is the definite axis crossings; the remainder needs more scrutiny. There will be an additional axis crossing if the the sum of the start angle and the remainder is > 90°. -*/ -#if 1 - int quadStart = (int)(a->angle[0] / QTR_TAU); - double qsRemain = a->angle[0] - ((double)quadStart * QTR_TAU); - int numAxes = (int)((a->angle[1] + qsRemain) / QTR_TAU); - - double axis[4] = { 0, 0, 0, 0 }; - axis[0] = rect.t, axis[1] = rect.l, axis[2] = rect.b, axis[3] = rect.r; - double box[4] = { 1.0, -1.0, -1.0, 1.0 }; - - for(int i=0; i QTR_TAU)) - rect.t = 1.0; - - if ((start < HALF_TAU) && (end > HALF_TAU)) - rect.l = -1.0; - - if ((start < THREE_QTR_TAU) && (end > THREE_QTR_TAU)) - rect.b = -1.0; - - if ((start < TAU) && (end > TAU)) - rect.r = 1.0; - - if ((start < (TAU + QTR_TAU)) && (end > (TAU + QTR_TAU))) - rect.t = 1.0; - - if ((start < (TAU + HALF_TAU)) && (end > (TAU + HALF_TAU))) - rect.l = -1.0; - - if ((start < (TAU + THREE_QTR_TAU)) && (end > (TAU + THREE_QTR_TAU))) - rect.b = -1.0; -#endif - - rect *= a->radius[0]; - rect.Translate(a->p[0]); + case OTPolyline: + { + Polyline * p = (Polyline *)obj; + rect = p->Bounds(); break; } @@ -2569,58 +2503,7 @@ void DrawingView::CheckObjectBounds(void) case OTArc: { Arc * a = (Arc *)obj; - - double start = a->angle[0]; - double end = start + a->angle[1]; - - // Swap 'em if the span is negative... - if (a->angle[1] < 0) - { - end = a->angle[0]; - start = end + a->angle[1]; - } - - // If the end of the arc is before the beginning, add 360 degrees - // to it - if (end < start) - end += TAU; - -#if 1 - int quadStart = (int)(a->angle[0] / QTR_TAU); - double qsRemain = a->angle[0] - ((double)quadStart * QTR_TAU); - int numAxes = (int)((a->angle[1] + qsRemain) / QTR_TAU); - - Rect bounds(sin(start), cos(start), sin(end), cos(end)); - const double box[4] = { 1.0, -1.0, -1.0, 1.0 }; - - for(int i=0; i QTR_TAU)) - bounds.t = 1.0; - - if ((start < HALF_TAU) && (end > HALF_TAU)) - bounds.l = -1.0; - - if ((start < THREE_QTR_TAU) && (end > THREE_QTR_TAU)) - bounds.b = -1.0; - - if ((start < TAU) && (end > TAU)) - bounds.r = 1.0; - - if ((start < (TAU + QTR_TAU)) && (end > (TAU + QTR_TAU))) - bounds.t = 1.0; - - if ((start < (TAU + HALF_TAU)) && (end > (TAU + HALF_TAU))) - bounds.l = -1.0; - - if ((start < (TAU + THREE_QTR_TAU)) && (end > (TAU + THREE_QTR_TAU))) - bounds.b = -1.0; -#endif - - bounds *= a->radius[0]; - bounds.Translate(a->p[0]); + Rect bounds = a->Bounds(); if (selection.Contains(bounds)) a->selected = true; @@ -2631,15 +2514,9 @@ void DrawingView::CheckObjectBounds(void) case OTPolyline: { Polyline * pl = (Polyline *)obj; - Rect r(((Object *)(pl->points[0]))->p[0]); + Rect bounds = pl->Bounds(); - for(int i=0; i<(pl->points.size()-1); i++) - { - r += ((Object *)(pl->points[i]))->p[0]; - r += ((Object *)(pl->points[i + 1]))->p[0]; - } - - if (selection.Contains(r)) + if (selection.Contains(bounds)) pl->selected = true; break; @@ -2745,7 +2622,7 @@ bool DrawingView::HitTest(Object * obj, Point point) else if ((distance * Global::zoom) < 5.0) obj->hitObject = true; - obj->hovered = (obj->hitPoint[0] || obj->hitPoint[1] || obj->hitObject ? true : false); + obj->hovered = (obj->hitPoint[0] || obj->hitPoint[1] || obj->hitObject); if ((oldHP0 != obj->hitPoint[0]) || (oldHP1 != obj->hitPoint[1]) || (oldHO != obj->hitObject)) needUpdate = true; @@ -2768,7 +2645,7 @@ bool DrawingView::HitTest(Object * obj, Point point) else if ((fabs(length - obj->radius[0]) * Global::zoom) < 2.0) obj->hitObject = true; - obj->hovered = (obj->hitPoint[0] || obj->hitObject ? true : false); + obj->hovered = (obj->hitPoint[0] || obj->hitObject); if ((oldHP != obj->hitPoint[0]) || (oldHO != obj->hitObject)) needUpdate = true; @@ -2790,7 +2667,7 @@ bool DrawingView::HitTest(Object * obj, Point point) // Get the span that we're pointing at... double span = angle - obj->angle[0]; - // N.B.: Still need to hit test the arc start & arc span handles... + // N.B.: Still need to hit test the arc start & arc span handles... [looks like it's DONE?] double spanAngle = obj->angle[0] + obj->angle[1]; Point handle1 = obj->p[0] + (Vector(cos(obj->angle[0]), sin(obj->angle[0])) * obj->radius[0]); Point handle2 = obj->p[0] + (Vector(cos(spanAngle), sin(spanAngle)) * obj->radius[0]); @@ -2818,7 +2695,7 @@ bool DrawingView::HitTest(Object * obj, Point point) else if (((fabs(length - obj->radius[0]) * Global::zoom) < 2.0) && (span < obj->angle[1])) obj->hitObject = true; - obj->hovered = (obj->hitPoint[0] || obj->hitPoint[1] || obj->hitPoint[2] || obj->hitObject ? true : false); + obj->hovered = (obj->hitPoint[0] || obj->hitPoint[1] || obj->hitPoint[2] || obj->hitObject); if ((oldHP0 != obj->hitPoint[0]) || (oldHP1 != obj->hitPoint[1]) || (oldHP2 != obj->hitPoint[2]) || (oldHO != obj->hitObject)) needUpdate = true; @@ -2826,6 +2703,86 @@ bool DrawingView::HitTest(Object * obj, Point point) break; } + case OTPolyline: + { + Polyline * pl = (Polyline *)obj; + bool oldHP0 = pl->hitPoint[0], oldHO = pl->hitObject; + pl->hitPoint[0] = pl->hitObject = false; + + for(long unsigned int i=0; i<(pl->points.size()-1); i++) + { + Point p1 = pl->points[i]; + Point p2 = pl->points[i + 1]; + + double dist1 = Vector::Magnitude(p1, point) * Global::zoom; + double dist2 = Vector::Magnitude(p2, point) * Global::zoom; + + // Check for endpoints of lines and/or arcs first + if (dist1 < 8.0) + { + pl->hitPoint[0] = true; + hoverPoint = p1; + hoverPointValid = true; + pl->ptNum = i; + } + else if (dist2 < 8.0) + { + pl->hitPoint[0] = true; + hoverPoint = p2; + hoverPointValid = true; + pl->ptNum = i + 1; + } + // Check for object (line/arc) last + else if (p1.b == 0) + { + double t = Geometry::ParameterOfLineAndPoint(p1, p2, point); + double objDist; + + // No bump == check for line proximity + if (t < 0.0) + objDist = dist1; + else if (t > 1.0) + objDist = dist2; + else + { + Line l(p1, p2); + Vector v1 = l.Vect(); + Vector v2(p1, point); + objDist = fabs((v1.x * v2.y - v2.x * v1.y) / l.Length()) * Global::zoom; + } + + if (objDist < 5.0) + pl->hitObject = true; + } + else + { + // We have a bump == check for arc proximity + Arc a = Geometry::Unpack(p1, p2, p1.b); + double length = Vector::Magnitude(a.p[0], point); + double angle = Vector::Angle(a.p[0], point); + double span = angle - a.angle[0]; + + // Ensure point span is positive if we have a positive arc span + if (span < 0 && a.angle[1] > 0) + span += TAU; + + // Ensure point span is negative if we have a negative arc span + if (span > 0 && a.angle[1] < 0) + span -= TAU; + + if (((fabs(length - a.radius[0]) * Global::zoom) < 2.5) && (fabs(span) < fabs(a.angle[1]))) + pl->hitObject = true; + } + } + + pl->hovered = (pl->hitPoint[0] || pl->hitObject); + + if ((oldHP0 != pl->hitPoint[0]) || (oldHO != pl->hitObject)) + needUpdate = true; + + break; + } + case OTDimension: { bool oldHP0 = obj->hitPoint[0], oldHP1 = obj->hitPoint[1], oldHP2 = obj->hitPoint[2], oldHP3 = obj->hitPoint[3], oldHP4 = obj->hitPoint[4], oldHO = obj->hitObject; @@ -2878,7 +2835,7 @@ bool DrawingView::HitTest(Object * obj, Point point) else if ((hCS2Point.Magnitude() * Global::zoom) < 8.0) obj->hitPoint[4] = true; - obj->hovered = (obj->hitPoint[0] || obj->hitPoint[1] || obj->hitPoint[2] || obj->hitPoint[3] || obj->hitPoint[4] || obj->hitObject ? true : false); + obj->hovered = (obj->hitPoint[0] || obj->hitPoint[1] || obj->hitPoint[2] || obj->hitPoint[3] || obj->hitPoint[4] || obj->hitObject); if ((oldHP0 != obj->hitPoint[0]) || (oldHP1 != obj->hitPoint[1]) || (oldHP2 != obj->hitPoint[2]) || (oldHP3 != obj->hitPoint[3]) || (oldHP4 != obj->hitPoint[4]) || (oldHO != obj->hitObject)) needUpdate = true; @@ -2898,7 +2855,7 @@ bool DrawingView::HitTest(Object * obj, Point point) if (r.Contains(point)) obj->hitObject = true; - obj->hovered = (obj->hitObject ? true : false); + obj->hovered = obj->hitObject; if (oldHO != obj->hitObject) needUpdate = true; @@ -3096,11 +3053,16 @@ N.B.: Mixing fixed length with fixed angle (and in this order) is probably *not* obj->p[0] = point; else if (obj->hitObject) { - double oldRadius = obj->length; - obj->radius[0] = Vector::Magnitude(obj->p[0], point); + if (shiftDown) + { + double oldRadius = obj->length; + obj->radius[0] = Vector::Magnitude(obj->p[0], point); - QString text = QObject::tr("Radius: %1\nScale: %2%"); - informativeText = text.arg(obj->radius[0], 0, 'f', 4).arg(obj->radius[0] / oldRadius * 100.0, 0, 'f', 0); + QString text = QObject::tr("Radius: %1\nScale: %2%"); + informativeText = text.arg(obj->radius[0], 0, 'f', 4).arg(obj->radius[0] / oldRadius * 100.0, 0, 'f', 0); + } + else + obj->p[0] += delta; } break; @@ -3169,16 +3131,34 @@ N.B.: Mixing fixed length with fixed angle (and in this order) is probably *not* { if (shiftDown) { - return; + obj->radius[0] = Vector::Magnitude(obj->p[0], point); + QString text = QObject::tr("Radius: %1"); + informativeText = text.arg(obj->radius[0], 0, 'f', 4); } - - obj->radius[0] = Vector::Magnitude(obj->p[0], point); - QString text = QObject::tr("Radius: %1"); - informativeText = text.arg(obj->radius[0], 0, 'f', 4); + else + obj->p[0] += delta; } break; + case OTPolyline: + { +#if 1 + // Do this for now... + ((Polyline *)obj)->Translate(delta); +// Polyline * pl = (Polyline *)obj; + +// for(long unsigned int i=0; ipoints.size(); i++) +// pl->points[i] += delta; +#else + Polyline * pl = (Polyline *)obj; + + for(long unsigned int i=0; i<(pl->points.size()-1); i++) +#endif + + break; + } + case OTDimension: if (obj->hitPoint[0]) obj->p[0] = point;