[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.   `._.-(,_..'--(,_..'`-.;.'


More information about the whatwg mailing list