WPF Arcs

Hi All,

I am currently in the process of porting a visual WPF application to a cloud framework and using Unity as the main canvas element. Within my application the user can draw primitive and complex shapes on the canvas, we do this using StreamGeometryContext from Microsoft. Below is some basic drawing code that allows us to draw a curved path.

``````ctx.BeginFigure(startEnd.GetPoint(), true, false);
ctx.LineTo(startBeginning.GetPoint(), true, true);
ctx.ArcTo(endBeginning.GetPoint(), outerEllipseSize, 0, false, startEllipseDirection, true, true);
ctx.LineTo(endEnd.GetPoint(), true, false);
ctx.ArcTo(startEnd.GetPoint(), innerEllipseSize, 0, false, endEllipseDirection, true, true);
``````

In unity I am using a LineRenderer to draw our primitive shapes and am having lots of success using it and am finding it quite easy to port across our legacy code. However I can not seem to find a suitable replacement For DrawArc, specifically this line

ctx.ArcTo(endBeginning.GetPoint(), outerEllipseSize, 0, false, startEllipseDirection, true, true);

ArcTo takes the following parameters

Point point,
Size size,
double rotationAngle,
bool isLargeArc,
SweepDirection sweepDirection,
bool isStroked,
bool isSmoothJoin

Would anyone be able to point me in the direction on how I could achieve the same effect as Microsoft’s ArcTo method in unity?

You could do this with the LineRenderer too… the trick is you have to synthesize the points on your arc.

This means you have a decision to make about how many intermediate points to synthesize.

You can just iterate a float angle from 0 to max, stepping by the gap to decide, and then use Quaternion.Euler(0,0,angle) to produce a rotation.

Using that rotation you can synthesize points… just hammering in some starter code:

``````Vector3 center = ... however you get this
float radius = ... however you get this

for( float angle = 0; angle <= 180; angle += 5)
{
// each point would be synthesized with:
Quaternion rotator = Quaternion.Euler( 0, 0, angle);

Vector3 offset = Vector3.up * radius;

Vector3 rotated = rotator * offset;

Vector3 finalPoint = center + rotated;
}
``````

Store those in an array, tell the LineRenderer about 'em!

Another approach would be using sprite shape and approximating arc using Bézier curve. It’s possible to get reasonable approximation for whole circle with just 4 points. Math is a bit more complicated, but there are plenty of articles discussing this. It’s not that bad if you are only using the existing formula instead of trying to prove that it’s optimal.

Although in the end it still generates a bunch triangles. So I am not sure there are too much benefits to it. It’s probably better to choose between line renderer and sprite shape based on which one makes it easier to implement the set of styling options you need like thickness, stroke style, end cap shape.