#include "arc.h"
#include <QtGui>
+#include "geometry.h"
#include "mathconstants.h"
#include "painter.h"
Vector oldLine = (p3 * (radius * 1.25)) + position;
pen = QPen(QColor(0x80, 0x80, 0x80), 1.0, Qt::DashLine);
painter->SetPen(pen);
- painter->DrawLine((int)position.x, (int)position.y, (int)oldLine.x, (int)oldLine.y);
+// painter->DrawLine((int)position.x, (int)position.y, (int)oldLine.x, (int)oldLine.y);
+ painter->DrawLine(position, oldLine);
}
// In rotating and setting the span, we draw a line showing where
text = text.arg(radius, 0, 'd', 4).arg(radius / oldRadius * 100.0, 0, 'd', 0);
}
+#if 0
pen = QPen(QColor(0x00, 0xFF, 0x00), 1.0, Qt::SolidLine);
painter->SetPen(pen);
painter->SetBrush(QBrush(QColor(0x40, 0xFF, 0x40, 0x9F)));
pen = QPen(QColor(0x00, 0x5F, 0xDF));
painter->SetPen(pen);
painter->DrawText(textRect, Qt::AlignVCenter, text);
+#else
+ painter->DrawInformativeText(text);
+#endif
}
}
/*virtual*/ bool Arc::Collided(Vector point)
{
- objectWasDragged = false;
-// Vector v1 = point - position; // Head minus tail (vector points at "point")
+ // Someone told us to fuck off, so we'll fuck off. :-)
+ if (ignoreClicks)
+ return false;
-#if 1
+ objectWasDragged = false;
bool hitSomething = HitTest(point);
draggingCenter = hitCenter;
draggingEdge = hitArc;
draggingRotate = hitRotate;
draggingSpan = hitSpan;
-#else
- // Check for collision with various things...
- hitHandle1 = false; // Moving
- hitHandle2 = false; // Rotation
- hitHandle3 = false; // Setting span of the arc
- hitHandle4 = false; // Resizing
-/*
-What we have:
-the center of the arc
-the starting angle
-the span of the arc
-The point on a unit circle given an angle a is x = cos(a), y = sin(a)
-This vector is already unitized, so all we need to do to get our point is to multiply it by
-radius (to get the length correct) and add it to the center point (to get the correct position).
-*/
- Vector v1 = point - position; // Head minus tail (vector points at "point")
- Point p1(cos(startAngle), sin(startAngle));
- Point p2(cos(startAngle + angleSpan), sin(startAngle + angleSpan));
- Vector handle2 = (p1 * radius) + position;
- Vector handle3 = (p2 * radius) + position;
- double pointerAngle = v1.Angle();
-#if 1
- // Center handle
- if (v1.Magnitude() < 10.0)
- hitHandle1 = true;
- // Span handle
- else if (Vector(handle3 - point).Magnitude() < 10.0)
- hitHandle3 = true;
- // Rotate handle
- else if (Vector(handle2 - point).Magnitude() < 10.0)
- hitHandle2 = true;
- // Resize handle (the arc itself)
- else if ((v1.Magnitude() < radius + 3.0) && (v1.Magnitude() > radius - 3.0)
- && AngleInArcSpan(pointerAngle))
- hitHandle4 = true;
-#endif
-#endif
+ // Now that we've done our hit testing on the non-snapped point, snap it if
+ // necessary...
+ if (snapToGrid)
+ point = SnapPointToGrid(point);
+
+ if (snapPointIsValid)
+ point = snapPoint;
/*
State Management:
so let's do like this:
*/
-// if (hitCenter || hitArc || hitRotate || hitSpan)
if (hitSomething)
{
oldState = state;
}
-/*virtual*/ void Arc::PointerMoved(Vector point)
+/*virtual*/ bool Arc::PointerMoved(Vector point)
{
// one other thing to check here for is if a modifier key is being held as well,
// to allow for multi-selection
else
state = OSInactive;
- return;
+ return false;
}
// The TLC will send these messages if the object is selected but not clicked on.
// objectWasDragged = true;
// needUpdate = false;
SaveHitState();
- HitTest(point);
+ bool hovered = HitTest(point);
needUpdate = HitStateChanged();
+
+ if (snapToGrid)
+ point = SnapPointToGrid(point);
+
+ if (snapPointIsValid)
+ point = snapPoint;
+
objectWasDragged = (draggingCenter | draggingEdge | draggingRotate | draggingSpan);
if (objectWasDragged)
// Why save this? For rendering code?
oldPoint = point;
// needUpdate = true;
+ return hovered;
}
multiply it by radius (to get the length correct) and add it to the center
point (to get the correct position).
*/
- Vector v1(point, position); // Head minus tail (vector points at "point")
+// Vector v1(point, position); // Head minus tail (vector points at "point")
+ Vector v1(position, point); // Head minus tail (vector points at "point")
Point p1(cos(startAngle), sin(startAngle));
Point p2(cos(startAngle + angleSpan), sin(startAngle + angleSpan));
Vector handle2 = (p1 * radius) + position;
hitArc = true;
#else
if ((length * Painter::zoom) < 8.0)
+ {
hitCenter = true;
+ snapPoint = position;
+ snapPointIsValid = true;
+ }
else if (((fabs(length - radius) * Painter::zoom) < 2.0)
&& AngleInArcSpan(pointerAngle))
hitArc = true;
else if ((Vector::Magnitude(handle2, point) * Painter::zoom) < 8.0)
+ {
hitRotate = true;
+ snapPoint = handle2;
+ snapPointIsValid = true;
+ }
else if ((Vector::Magnitude(handle3, point) * Painter::zoom) < 8.0)
+ {
hitSpan = true;
+ snapPoint = handle3;
+ snapPointIsValid = true;
+ }
#endif
return (hitCenter || hitArc || hitRotate || hitSpan ? true : false);
QPointF p2(cos(end), sin(end));
QRectF bounds(p1, p2);
+#if 0
// Swap X/Y coordinates if they're backwards...
if (bounds.left() > bounds.right())
{
bounds.setBottom(bounds.top());
bounds.setTop(temp);
}
+#else
+ bounds = bounds.normalized();
+#endif
// If the end of the arc is before the beginning, add 360 degrees to it
if (end < start)
/*virtual*/ void Arc::Enumerate(FILE * file)
{
- fprintf(file, "ARC (%lf,%lf) %lf, %lf, %lf\n", position.x, position.y, radius, startAngle, angleSpan);
+ fprintf(file, "ARC %i (%lf,%lf) %lf, %lf, %lf\n", layer, position.x, position.y, radius, startAngle, angleSpan);
}
return new Arc(position, radius, startAngle, angleSpan, parent);
}
+
+/*virtual*/ void Arc::Rotate(Point point, double angle)
+{
+ Point c1 = Geometry::RotatePointAroundPoint(position, point, angle);
+ Point ap1(cos(startAngle), sin(startAngle));
+ Point angleStartPoint = (ap1 * radius) + position;
+ Point c2 = Geometry::RotatePointAroundPoint(angleStartPoint, point, angle);
+
+ position = c1;
+ startAngle = Vector(c1, c2).Angle();
+}
+
+
+/*virtual*/ void Arc::Mirror(Point p1, Point p2)
+{
+ Point c1 = Geometry::MirrorPointAroundLine(position, p1, p2);
+ Point ap1(cos(startAngle + angleSpan), sin(startAngle + angleSpan));
+ Point angleEndPoint = (ap1 * radius) + position;
+ Point c2 = Geometry::MirrorPointAroundLine(angleEndPoint, p1, p2);
+
+ position = c1;
+ startAngle = Vector(c2, c1).Angle();
+}
+
+
+/*virtual*/ void Arc::Save(void)
+{
+ Object::Save();
+ oldRadius2 = radius;
+ oldStartAngle = startAngle;
+ oldAngleSpan = angleSpan;
+}
+
+
+/*virtual*/ void Arc::Restore(void)
+{
+ Object::Restore();
+ radius = oldRadius2;
+ startAngle = oldStartAngle;
+ angleSpan = oldAngleSpan;
+}
+