# [whatwg] Canvas arcTo all points on a line

Ian Hickson ian at hixie.ch
Thu Apr 30 16:05:38 PDT 2009

```On Sat, 27 Dec 2008, Dirk Schulze wrote:
>
> 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.

On Wed, 21 Jan 2009, Philip Taylor wrote:
>
> 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.

On Sat, 27 Dec 2008, Dirk Schulze wrote:
>
> 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.

On Sat, 27 Dec 2008, Dirk Schulze wrote:
>
> I believe adding an infinite far away point is wrong and insteaed
> nothing should be drawn at all and I would like to explain my reason:
>
> Imagine 2 vectors. One from (x1, y1) to (x0, y0) and one from (x1, y1)
> to (x2, y2). For
>
> moveTo(100, 0);
> arcTo(150,0, 50, 0, 10);
>
> the angle between the two vectors is 0. Now we want to calculate the two
> points on the tangents of the circle with the radius r. r is not null
> (first point of the specification for arcTo). Now put it to a system of
> equations and you won't get a solution. It's unresolveable. Why is
> something allowed, that is not calculateable?
>
> The next reason is, that infinite or NaN values are not alowed for
> lineTo and moveTo , ... . But it's possible to get support for infinte
> indirectly with arcTo (see comment above). And how to deal with a
> infinite far away point? A lineTo would never reach this point, it's
> infinite far away. Instead we have to draw a line parallel to the
> infinite long line, created by arcTo (and it's infinite long too).

On Wed, 21 Jan 2009, Philip Taylor wrote:
>
> 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.

On Wed, 21 Jan 2009, Calogero Alex Baldacchino wrote:
>
> I haven't checked this part of the spec insofar; looking at the image
> you posted it seems the 3 points are used as control points in a
> somewhat algorithm to draw curve lines; personally, thinking to an API
> function to draw arcs, I prefer to have the specified points as being
> part of the arc itself (e.g., the two external ones are the extremes of
> a convex elliptical arc). Anyway, certainly what you say makes sense for
> an arc degenering to a line (that is, if all points lay on the same
> line). Assuming the angular coefficient and the start point of the line
> are known, it is easy to find the intersection between it and a clip
> region (through the mean-point algorithm) -- it should be the same with
> a (x2, y2) point very close with the (x0, y0)--(x1, y1) segment, that is
> if under a certain threshold one can't drow an arc and instead the
> result must be approximated to a half-infinite line (I think all an
> implementation needs is to remember an infinite line has been drawn and
> the last point in the subpath is infinitely far, so it can draw a
> parallel line when .lineTo() is invocked).

On Wed, 21 Jan 2009, Philip Taylor wrote:
>
> After some discussion on IRC, it seems this part of the spec is not a
> great idea.
>
> As I understand it, the low-level graphics APIs have limited coordinate
> range and rely on the "User agents may impose implementation-specific
> limits on otherwise unconstrained inputs, e.g. to prevent denial of
> service attacks, to guard against running out of memory, or to work
> around platform-specific limitations." clause (and common sense) to let
> them have undefined behaviour when people use really large coordinate
> values. The infinitely-distant point required by arcTo is a really large
> coordinate value, but we don't want this case to be undefined behaviour
> (because it can occur with nice small integer input values and people
> might accidentally use it).
>
> Implementing the behaviour currently in the spec (with the
> infinitely-distant point) is not trivial, because it requires code
> unique to that special case (rather than falling naturally out of an
> implementation of the rest of arcTo's behaviour) and has to be careful
> to act enough like an infinitely-distance point while remaining within
> the implementation limits.
>
> And it seems like a rare edge case where people disagree on whether the
> output is sensible, and nobody is really going to care what the output
> is (as long as it's well defined); so it doesn't seem worthwhile having
> everyone understand and implement the non-trivial behaviour that's in
> the spec.
>
> So, in the interest of having something that implementors are more
> likely to converge on, I'd suggest replacing the behaviour in that case
> (the "the direction from (x0, y0) to (x1, y1) is the opposite of the
> direction from (x1, y1) to (x2, y2)" case) with simply drawing a
> straight line from (x0, y0) to (y1, y1), which is easy and apparently is
> what Safari on OS X already does. It's also the same as the other case
> in that paragraph, so the whole paragraph can be collapsed to:
>
>   "Otherwise, if the points (x0, y0), (x1, y1), and (x2, y2) all lie on
> a single straight line, then the method must add the point (x1, y1) to
> the subpath, and connect that point to the previous point (x0, y0) by a
> straight line."

So changed.

--
Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
```