[whatwg] Canvas arcTo all points on a line

Philip Taylor excors+whatwg at gmail.com
Wed Jan 21 06:45:07 PST 2009

```On Sat, Dec 27, 2008 at 9:37 AM, Dirk Schulze <vbs85 at gmx.de> wrote:
> Hi,
>
> have two questions to the "all points on a line" part of canvas' arcTo.
> A short example:
>
> moveTo(50,0);
> arcTo(100,0,  0,0, 10);
>
> This should add a new, from p1 infinite far away, point to the subpath
> and draw a straight line to it.
>
> Two questions.
>
> 1) If I add lineTo(50, 50); after arcTo(..). Wouldn't it draw a "quasi
> parallel" line to the line of arcTo? Because (Xx, Yx) (mentioned in the
> spec) is infinite far away. That means, we will never reach this point
> in reality.

It should draw a really parallel line, with one end at (50,50) and the
other end infinitely far away in the direction determined by the
arcTo.

> 2) We don't allow infinite values for moveTo or lineTo, but can make
> this happen with arcTo.
> The example above would be the same as lineTo(-Infinite, 0);
> But we can make moveTo(-Infinite, 0) too with the example above. Just
> make strokeStyle transparent, use arcTo from above and you're done. And
> moveTo(infinite, infinite); would be possible too.

You can moveTo(-1e+300, 0) and moveTo(1e+300, 2e+300), which are much
more similar to what arcTo is meant to do.

Considering the general case where the arcTo's points are not
perfectly horizontal, the idea is that the point is not simply a point
with coordinates (+/-Infinity, +/-Infinity) - it's really the
(theoretical) limit of a point with coordinates (x+dx*t, y+dy*t) as t
approaches infinity, where x,y,dx,dy represent the position/direction
of the (x1,y1)--(x2,y2) line.

Where the spec says "(x∞, y∞) is the point that is infinitely far away
from (x1, y1), that lies on the same line as (x0, y0), (x1, y1), and
(x2, y2)", you could read it as "...the point that is very very far
away from ...", e.g. take the (x1,y1)--(x2,y2) line and then move
1e+100 units in that direction, and it would be good enough that
nobody would notice the tiny error.

You already have to handle something very similar to this case,
because (x2,y2) might be very very close to the line (x0,y0)--(x1,y1),
which means the start/end tangent points will be very very far away in
the appropriate direction. The special case where (x2,y2) is precisely
on the line is not really special - the points are just even further
(infinitely far) away in that direction.

As a concrete example: see
<http://philip.html5.org/demos/canvas/arcto-inf.html>, which I believe
should have output like
<http://philip.html5.org/demos/canvas/arcto-inf.png> (from Safari
3.0.4 for Windows). As (x2,y2) gets closer to the line of the first
two points, the start/end tangent points are pushed further over to
the left. When y2=0.1 they're far enough away that the two straight
lines are nearly horizontal; when y2=0 it's basically the same, except
now they're precisely horizontal.

So I think the spec's behaviour makes sense from a theoretical
perspective, because it avoids any discontinuities in the output when
the input variables are changed a tiny bit. And it made sense from a
practical perspective, because it matched the behaviour of Safari 3.0
(though apparently things have changed in 3.1).

But I don't know if it makes sense from the perspective of someone
who's got to write an independent implementation of it. Does the above
explanation make more sense than the text in the spec? and if so, does
it seem implementable? If so, it seems best to keep the spec's
behaviour and try to clarify the spec's text. But this doesn't seem
like an important case where users will be unhappy if e.g. the arcTo
call draws nothing when all the points are on the same line, so if
it's still a pain to implement the spec's behaviour then I would be
happy with changing what the spec requires.

--
Philip Taylor
excors at gmail.com

```