Changed the arc functions to take a start angle and a sweep amount instead of a start angle and an end angle. This makes it easier to reason about sweeps > 2π radians.

This commit is contained in:
Pietro Gagliardi 2015-10-09 21:51:43 -04:00
parent 9adf4cef86
commit 2c7ed07747
5 changed files with 21 additions and 22 deletions

View File

@ -30,7 +30,7 @@ void uiDrawPathNewFigure(uiDrawPath *p, double x, double y)
CGPathMoveToPoint(p->path, NULL, x, y); CGPathMoveToPoint(p->path, NULL, x, y);
} }
void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double endAngle) void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep)
{ {
double sinStart, cosStart; double sinStart, cosStart;
double startx, starty; double startx, starty;
@ -42,7 +42,7 @@ void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, d
startx = xCenter + radius * cosStart; startx = xCenter + radius * cosStart;
starty = yCenter + radius * sinStart; starty = yCenter + radius * sinStart;
CGPathMoveToPoint(p->path, NULL, startx, starty); CGPathMoveToPoint(p->path, NULL, startx, starty);
uiDrawPathArcTo(p, xCenter, yCenter, radius, startAngle, endAngle); uiDrawPathArcTo(p, xCenter, yCenter, radius, startAngle, sweep);
} }
void uiDrawPathLineTo(uiDrawPath *p, double x, double y) void uiDrawPathLineTo(uiDrawPath *p, double x, double y)
@ -52,14 +52,15 @@ void uiDrawPathLineTo(uiDrawPath *p, double x, double y)
CGPathAddLineToPoint(p->path, NULL, x, y); CGPathAddLineToPoint(p->path, NULL, x, y);
} }
void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double endAngle) void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep)
{ {
if (p->ended) if (p->ended)
complain("attempt to add arc to ended path in uiDrawPathArcTo()"); complain("attempt to add arc to ended path in uiDrawPathArcTo()");
// TODO wasn't there a relative function?
CGPathAddArc(p->path, NULL, CGPathAddArc(p->path, NULL,
xCenter, yCenter, xCenter, yCenter,
radius, radius,
startAngle, endAngle, startAngle, startAngle + sweep,
NO); NO);
} }

View File

@ -80,16 +80,14 @@ static void drawOriginal(uiAreaDrawParams *p)
400, 100, 400, 100,
50, 50,
30. * (M_PI / 180.), 30. * (M_PI / 180.),
// note the end angle here 300. * (M_PI / 180.));
// in GDI, the second angle to AngleArc() is relative to the start, not to 0
330. * (M_PI / 180.));
// TODO add a checkbox for this // TODO add a checkbox for this
uiDrawPathLineTo(path, 400, 100); uiDrawPathLineTo(path, 400, 100);
uiDrawPathNewFigureWithArc(path, uiDrawPathNewFigureWithArc(path,
510, 100, 510, 100,
50, 50,
30. * (M_PI / 180.), 30. * (M_PI / 180.),
330. * (M_PI / 180.)); 300. * (M_PI / 180.));
uiDrawPathCloseFigure(path); uiDrawPathCloseFigure(path);
uiDrawPathEnd(path); uiDrawPathEnd(path);
sp.Cap = uiDrawLineCapFlat; sp.Cap = uiDrawLineCapFlat;
@ -210,7 +208,7 @@ static void drawArcs(uiAreaDrawParams *p)
uiDrawPathNewFigureWithArc(path, uiDrawPathNewFigureWithArc(path,
x, y, x, y,
rad, rad,
(M_PI / 4), (M_PI / 4) + angle); (M_PI / 4), angle);
angle += add; angle += add;
x += 2 * rad + step; x += 2 * rad + step;
if (i % 6 == 5) { if (i % 6 == 5) {

4
ui.h
View File

@ -379,11 +379,11 @@ _UI_EXTERN uiDrawPath *uiDrawNewPath(uiDrawFillMode fillMode);
_UI_EXTERN void uiDrawFreePath(uiDrawPath *p); _UI_EXTERN void uiDrawFreePath(uiDrawPath *p);
_UI_EXTERN void uiDrawPathNewFigure(uiDrawPath *p, double x, double y); _UI_EXTERN void uiDrawPathNewFigure(uiDrawPath *p, double x, double y);
_UI_EXTERN void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double endAngle); _UI_EXTERN void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep);
_UI_EXTERN void uiDrawPathLineTo(uiDrawPath *p, double x, double y); _UI_EXTERN void uiDrawPathLineTo(uiDrawPath *p, double x, double y);
// notes: angles are both relative to 0 and go counterclockwise // notes: angles are both relative to 0 and go counterclockwise
// TODO is the initial line segment on cairo and OS X a proper join? // TODO is the initial line segment on cairo and OS X a proper join?
_UI_EXTERN void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double endAngle); _UI_EXTERN void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep);
_UI_EXTERN void uiDrawPathBezierTo(uiDrawPath *p, double c1x, double c1y, double c2x, double c2y, double endX, double endY); _UI_EXTERN void uiDrawPathBezierTo(uiDrawPath *p, double c1x, double c1y, double c2x, double c2y, double endX, double endY);
// TODO quadratic bezier // TODO quadratic bezier
_UI_EXTERN void uiDrawPathCloseFigure(uiDrawPath *p); _UI_EXTERN void uiDrawPathCloseFigure(uiDrawPath *p);

View File

@ -55,7 +55,7 @@ void uiDrawPathNewFigure(uiDrawPath *p, double x, double y)
add(p, &piece); add(p, &piece);
} }
void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double endAngle) void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep)
{ {
struct piece piece; struct piece piece;
@ -64,7 +64,7 @@ void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, d
piece.d[1] = yCenter; piece.d[1] = yCenter;
piece.d[2] = radius; piece.d[2] = radius;
piece.d[3] = startAngle; piece.d[3] = startAngle;
piece.d[4] = endAngle; piece.d[4] = sweep;
add(p, &piece); add(p, &piece);
} }
@ -78,7 +78,7 @@ void uiDrawPathLineTo(uiDrawPath *p, double x, double y)
add(p, &piece); add(p, &piece);
} }
void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double endAngle) void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep)
{ {
struct piece piece; struct piece piece;
@ -87,7 +87,7 @@ void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radiu
piece.d[1] = yCenter; piece.d[1] = yCenter;
piece.d[2] = radius; piece.d[2] = radius;
piece.d[3] = startAngle; piece.d[3] = startAngle;
piece.d[4] = endAngle; piece.d[4] = sweep;
add(p, &piece); add(p, &piece);
} }
@ -154,7 +154,7 @@ static void runPath(uiDrawPath *p, cairo_t *cr)
piece->d[0], piece->d[0],
piece->d[1], piece->d[1],
piece->d[2], piece->d[2],
piece->d[4], piece->d[3] + piece->d[4],
piece->d[3]); piece->d[3]);
break; break;
case lineTo: case lineTo:

View File

@ -165,7 +165,7 @@ static void doDrawArc(ID2D1GeometrySink *sink, double startX, double startY, dou
ID2D1GeometrySink_AddArc(sink, &as); ID2D1GeometrySink_AddArc(sink, &as);
} }
void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double endAngle) void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep)
{ {
double startX, startY; double startX, startY;
double endX, endY; double endX, endY;
@ -175,8 +175,8 @@ void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, d
uiDrawPathNewFigure(p, startX, startY); uiDrawPathNewFigure(p, startX, startY);
// draw the arc // draw the arc
arcEndpoint(xCenter, yCenter, radius, endAngle, &endX, &endY); arcEndpoint(xCenter, yCenter, radius, startAngle + sweep, &endX, &endY);
doDrawArc(p->sink, startX, startY, endX, endY, radius, endAngle - startAngle); doDrawArc(p->sink, startX, startY, endX, endY, radius, sweep);
} }
void uiDrawPathLineTo(uiDrawPath *p, double x, double y) void uiDrawPathLineTo(uiDrawPath *p, double x, double y)
@ -188,7 +188,7 @@ void uiDrawPathLineTo(uiDrawPath *p, double x, double y)
ID2D1GeometrySink_AddLine(p->sink, pt); ID2D1GeometrySink_AddLine(p->sink, pt);
} }
void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double endAngle) void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep)
{ {
double startX, startY; double startX, startY;
double endX, endY; double endX, endY;
@ -198,8 +198,8 @@ void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radiu
uiDrawPathLineTo(p, startX, startY); uiDrawPathLineTo(p, startX, startY);
// draw the arc // draw the arc
arcEndpoint(xCenter, yCenter, radius, endAngle, &endX, &endY); arcEndpoint(xCenter, yCenter, radius, startAngle + sweep, &endX, &endY);
doDrawArc(p->sink, startX, startY, endX, endY, radius, endAngle - startAngle); doDrawArc(p->sink, startX, startY, endX, endY, radius, sweep);
} }
void uiDrawPathBezierTo(uiDrawPath *p, double c1x, double c1y, double c2x, double c2y, double endX, double endY) void uiDrawPathBezierTo(uiDrawPath *p, double c1x, double c1y, double c2x, double c2y, double endX, double endY)