AFAICT, still doesn���t explain how to draw an ellipse with constant stroke path width, which was the original question :)
On 22 Apr 2014, at 2:23 , Igor Stasenko <siguctua@gmail.com> wrote:
> as for why there's 4 arc segments instead of one, its because
> of bad approximation, when drawing more that 90 degree arcs.
>
> also, in athens, arc segment is defined with following inputs:
> - end point of previous segment (implicit)
> - angle
> - direction (clockwise/counterclockwise)
> - end point
>
> the radius, therefore calculated automatically, because with given set of parameters there's only one way to draw an arc connecting given points.
>
> Now if you put angle of 360 degrees, you cannot draw arc without specifying radius,
> because your end points will coincide, which means there's infinite number of ways to draw full circle passing through a single point, with any radius.
>
> cairo using different inputs for specifying arc segments..
> - center, radius, start angle, end angle
>
> the problem with such parametrization is that it is completely separate from rest of commands (line/move/bezier etc).. and you will be very lucky if your arc will be connected with rest of your path.. because arc's starting point depends on start angle, instead of last point of previous path segment.
>
> this was the main reason to use more appropriate parametrization to get rid of inconsistency.. while losing ability to draw full circle with single command..
One way is to not use a transformed circle path altogether, but draw the actual ellipsis path using cubic beziers:
http://www.charlespetzold.com/blog/2012/12/Bezier-Circles-and-Bezier-Ellipses.html
ellipsisOfExtent := [:builder :anExtent | | halfX halfY |
�� �� �� �� �� �� �� �� halfX := anExtent x / 2.
�� �� �� �� �� �� �� �� halfY := anExtent y / 2.
�� �� �� �� �� �� �� �� ���We expect relative builder, and start the ellipsis at anExtent x / 2 @ 0"
�� �� �� �� �� �� �� �� builder
�� �� �� �� �� �� �� �� �� �� �� �� curveVia: 0@(halfY negated * 0.55) and: (0.45 * halfX)@halfY negated to: halfX@ halfY negated;
�� �� �� �� �� �� �� �� �� �� �� �� curveVia: halfX* 0.55 @ 0 and: halfX@ (0.45 * halfY) to: halfX @ halfY;
�� �� �� �� �� �� �� �� �� �� �� �� curveVia: 0 @ (halfY * 0.55 ) and: (0.45 * halfX negated @ halfY) to: halfX negated @ halfY;
�� �� �� �� �� �� �� �� �� �� �� �� curveVia: (halfX negated * 0.55) @ 0 and: halfX negated @ (halfY negated * 0.45) to: halfX negated @ halfY negated;
�� �� �� �� �� �� �� �� �� �� �� �� close].
AthensSceneView new�� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� builder moveTo: 10@60.
�� �� �� �� scene: [ :can |
�� �� �� �� �� �� �� �� | path |
�� �� �� �� path := can
�� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� createPath: [ :builder |
�� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� ellipsisOfExtent value: builder value: 200@100 ].
�� �� �� �� (can
�� �� �� �� �� �� �� �� setStrokePaint: Color red)
�� �� �� �� �� �� �� �� width: 8 asFloat.
�� �� �� �� can drawShape: ��path ] ;
�� �� �� �� openInWindow
Cheers,
Henry