X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdrawingview.cpp;h=39196a753646a9eb7929e8d699b9e21f89c8fce3;hb=3c890e51a9763ffcee49e15753453a7da248272b;hp=3b6f92c6663c363bba9b1cf68e006793f101a7e0;hpb=41644f6a841b45cb6f1f7a96c93fd550f67a7974;p=architektonas diff --git a/src/drawingview.cpp b/src/drawingview.cpp index 3b6f92c..39196a7 100644 --- a/src/drawingview.cpp +++ b/src/drawingview.cpp @@ -133,7 +133,7 @@ void DrawingView::DrawBackground(Painter * painter) painter->SetBrush(0xF0F0F0); painter->SetPen(0xF0F0F0, 1, 1); - painter->DrawRect(QRectF(QPointF(ul.x, ul.y), QPointF(br.x, br.y))); + painter->DrawRect(Rect(ul, br)); double spacing = Global::gridSpacing; @@ -455,6 +455,41 @@ void DrawingView::RenderObjects(Painter * painter, VPVector & v, int layer, bool break; + case OTPolyline: + { + painter->SetBrush(QBrush(Qt::NoBrush)); + Polyline * pl = (Polyline *)obj; + Point lastp; + double lastbump; + + for(VPVectorIter i=pl->points.begin(); i!=pl->points.end(); 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]); + } + + lastp = p; + lastbump = bump; + } + else + { + lastp = ((Object *)(*i))->p[0]; + lastbump = ((Object *)(*i))->length; + } + } + + break; + } + case OTDimension: { Dimension * d = (Dimension *)obj; @@ -632,15 +667,12 @@ Where is the text offset? It looks like it's drawing in the center, but obvious break; } +#if 0 case OTPolygon: { break; } - - case OTPolyline: - { - break; - } +#endif case OTContainer: { @@ -1975,8 +2007,8 @@ void DrawingView::mousePressEvent(QMouseEvent * event) // Didn't hit any object and not using a tool, so do a selection // rectangle Global::selectionInProgress = true; - Global::selection.setTopLeft(QPointF(point.x, point.y)); - Global::selection.setBottomRight(QPointF(point.x, point.y)); + Global::selection.l = Global::selection.r = point.x; + Global::selection.t = Global::selection.b = point.y; select = GetSelection(); } else if (event->button() == Qt::MiddleButton) @@ -1998,7 +2030,8 @@ void DrawingView::mouseMoveEvent(QMouseEvent * event) } Vector point = Painter::QtToCartesianCoords(Vector(event->x(), event->y())); - Global::selection.setBottomRight(QPointF(point.x, point.y)); + Global::selection.r = point.x; + Global::selection.b = point.y; // Only needs to be done here, as mouse down is always preceded by movement Global::snapPointIsValid = false; hoveringIntersection = false; @@ -2411,12 +2444,40 @@ Rect DrawingView::GetObjectExtents(Object * 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]; + } + 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; @@ -2438,6 +2499,7 @@ Rect DrawingView::GetObjectExtents(Object * obj) 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]); @@ -2477,6 +2539,8 @@ void DrawingView::CheckObjectBounds(void) { Object * obj = (Object *)(*i); obj->selected = false; + Rect selection = Global::selection; + selection.Normalize(); switch (obj->type) { @@ -2485,7 +2549,7 @@ void DrawingView::CheckObjectBounds(void) { Line * l = (Line *)obj; - if (Global::selection.contains(l->p[0].x, l->p[0].y) && Global::selection.contains(l->p[1].x, l->p[1].y)) + if (selection.Contains(l->p[0]) && selection.Contains(l->p[1])) l->selected = true; break; @@ -2494,8 +2558,9 @@ void DrawingView::CheckObjectBounds(void) case OTCircle: { Circle * c = (Circle *)obj; + Vector radVec(c->radius[0], c->radius[0]); - if (Global::selection.contains(c->p[0].x - c->radius[0], c->p[0].y - c->radius[0]) && Global::selection.contains(c->p[0].x + c->radius[0], c->p[0].y + c->radius[0])) + if (selection.Contains(c->p[0] - radVec) && selection.Contains(c->p[0] + radVec)) c->selected = true; break; @@ -2507,73 +2572,85 @@ void DrawingView::CheckObjectBounds(void) double start = a->angle[0]; double end = start + a->angle[1]; - QPointF p1(cos(start), sin(start)); - QPointF p2(cos(end), sin(end)); - QRectF bounds(p1, p2); -#if 1 - // Swap X/Y coordinates if they're backwards... - if (bounds.left() > bounds.right()) - { - double temp = bounds.left(); - bounds.setLeft(bounds.right()); - bounds.setRight(temp); - } - - if (bounds.bottom() > bounds.top()) + // Swap 'em if the span is negative... + if (a->angle[1] < 0) { - double temp = bounds.bottom(); - bounds.setBottom(bounds.top()); - bounds.setTop(temp); + end = a->angle[0]; + start = end + a->angle[1]; } -#else - // Doesn't work as advertised! For shame! - bounds = bounds.normalized(); -#endif // 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.setTop(1.0); + bounds.t = 1.0; if ((start < HALF_TAU) && (end > HALF_TAU)) - bounds.setLeft(-1.0); + bounds.l = -1.0; if ((start < THREE_QTR_TAU) && (end > THREE_QTR_TAU)) - bounds.setBottom(-1.0); + bounds.b = -1.0; if ((start < TAU) && (end > TAU)) - bounds.setRight(1.0); + bounds.r = 1.0; if ((start < (TAU + QTR_TAU)) && (end > (TAU + QTR_TAU))) - bounds.setTop(1.0); + bounds.t = 1.0; if ((start < (TAU + HALF_TAU)) && (end > (TAU + HALF_TAU))) - bounds.setLeft(-1.0); + bounds.l = -1.0; if ((start < (TAU + THREE_QTR_TAU)) && (end > (TAU + THREE_QTR_TAU))) - bounds.setBottom(-1.0); + bounds.b = -1.0; +#endif - bounds.setTopLeft(QPointF(bounds.left() * a->radius[0], bounds.top() * a->radius[0])); - bounds.setBottomRight(QPointF(bounds.right() * a->radius[0], bounds.bottom() * a->radius[0])); - bounds.translate(a->p[0].x, a->p[0].y); + bounds *= a->radius[0]; + bounds.Translate(a->p[0]); - if (Global::selection.contains(bounds)) + if (selection.Contains(bounds)) a->selected = true; break; } + case OTPolyline: + { + Polyline * pl = (Polyline *)obj; + Rect r(((Object *)(pl->points[0]))->p[0]); + + 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)) + pl->selected = true; + + break; + } + case OTText: { Text * t = (Text *)obj; Rect r(obj->p[0], Point(t->p[0].x + t->extents.Width(), t->p[0].y - t->extents.Height())); - if (Global::selection.contains(r.l, r.t) && Global::selection.contains(r.r, r.b)) + if (selection.Contains(r)) t->selected = true; break; @@ -2583,7 +2660,7 @@ void DrawingView::CheckObjectBounds(void) { Container * c = (Container *)obj; - if (Global::selection.contains(c->p[0].x, c->p[0].y) && Global::selection.contains(c->p[1].x, c->p[1].y)) + if (selection.Contains(c->p[0]) && selection.Contains(c->p[1])) c->selected = true; break; @@ -3049,14 +3126,14 @@ N.B.: Mixing fixed length with fixed angle (and in this order) is probably *not* obj->angle[1] += TAU; QString text = QObject::tr("Span: %1") + QChar(0x00B0) + QObject::tr("\n%2") + QChar(0x00B0) + QObject::tr(" - %3") + QChar(0x00B0); - informativeText = text.arg(obj->angle[1] * RADIANS_TO_DEGREES, 0, 'd', 4).arg(obj->angle[0] * RADIANS_TO_DEGREES, 0, 'd', 2).arg((obj->angle[0] + obj->angle[1]) * RADIANS_TO_DEGREES, 0, 'd', 2); + informativeText = text.arg(obj->angle[1] * RADIANS_TO_DEGREES, 0, 'f', 4).arg(obj->angle[0] * RADIANS_TO_DEGREES, 0, 'f', 2).arg((obj->angle[0] + obj->angle[1]) * RADIANS_TO_DEGREES, 0, 'f', 2); return; } double angle = Vector::Angle(obj->p[0], point); obj->angle[0] = angle; QString text = QObject::tr("Start angle: %1") + QChar(0x00B0); - informativeText = text.arg(obj->angle[0] * RADIANS_TO_DEGREES, 0, 'd', 4); + informativeText = text.arg(obj->angle[0] * RADIANS_TO_DEGREES, 0, 'f', 4); } else if (obj->hitPoint[2]) { @@ -3070,7 +3147,7 @@ N.B.: Mixing fixed length with fixed angle (and in this order) is probably *not* obj->angle[1] += TAU; QString text = QObject::tr("Span: %1") + QChar(0x00B0) + QObject::tr("\n%2") + QChar(0x00B0) + QObject::tr(" - %3") + QChar(0x00B0); - informativeText = text.arg(obj->angle[1] * RADIANS_TO_DEGREES, 0, 'd', 4).arg(obj->angle[0] * RADIANS_TO_DEGREES, 0, 'd', 2).arg((obj->angle[0] + obj->angle[1]) * RADIANS_TO_DEGREES, 0, 'd', 2); + informativeText = text.arg(obj->angle[1] * RADIANS_TO_DEGREES, 0, 'f', 4).arg(obj->angle[0] * RADIANS_TO_DEGREES, 0, 'f', 2).arg((obj->angle[0] + obj->angle[1]) * RADIANS_TO_DEGREES, 0, 'f', 2); return; } @@ -3080,8 +3157,13 @@ N.B.: Mixing fixed length with fixed angle (and in this order) is probably *not* if (obj->angle[0] < 0) obj->angle[0] += TAU; + double endAngle = obj->angle[0] + obj->angle[1]; + + if (endAngle > TAU) + endAngle -= TAU; + QString text = QObject::tr("End angle: %1") + QChar(0x00B0); - informativeText = text.arg((obj->angle[0] + obj->angle[1]) * RADIANS_TO_DEGREES, 0, 'd', 4); + informativeText = text.arg(endAngle * RADIANS_TO_DEGREES, 0, 'f', 4); } else if (obj->hitObject) { @@ -3092,7 +3174,7 @@ N.B.: Mixing fixed length with fixed angle (and in this order) is probably *not* obj->radius[0] = Vector::Magnitude(obj->p[0], point); QString text = QObject::tr("Radius: %1"); - informativeText = text.arg(obj->radius[0], 0, 'd', 4); + informativeText = text.arg(obj->radius[0], 0, 'f', 4); } break;