- From: Ian Hickson <ian@hixie.ch>
- Date: Thu, 30 Apr 2009 23:05:38 +0000 (UTC)
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. `._.-(,_..'--(,_..'`-.;.'
Received on Thursday, 30 April 2009 16:05:38 UTC