Re: [whatwg] Canvas arcTo method
Hi Ian, Yeah, that's why the spec hand-waves to transform the line too... but I agree that that doesn't really work. Do you have any suggestion of how to spec this better? This is the most general arcTo situation: setTransform(M0) lineTo(x0, y0) setTransform(M) arcTo(x1, y1, x2, y2, radius, ...) To generate the arc we need three points: P0, P1, P2, all in the same coordinate system. The three points are: P0 = inverse(M) * M0 * (x0, y0) P1 = (x1, y1) P2 = (x2, y2) We are transforming (x0, y0) by M0, which is the transform current at the time the point was added to the path. This gives us a point in canvas coordinates that we can transform by the inverse of M, which is the transform current at the time the arc is added to the path. This gives us a point in the same coordinate space as P1 and P2. In the common case where M = M0, the transforms cancel each other out and P0 = (x0, y0). Once we have the three points in the same coordinate space we can generate the arc and then apply M to all of the points in the generated arc to draw the arc in canvas coordinates. Does this make sense? I don't think it is possible to specify this process without requiring an inverse transformation somewhere, to get all three points into the same coordinate space. If so, it is probably best to describe this explicitly, rather than ambiguously implying the need for it. Best regards, Michael
Re: [whatwg] Canvas arcTo method
On Mon, Sep 3, 2012 at 8:58 AM, Ian Hickson i...@hixie.ch wrote: Does it work if you just transform all the points and the line? (Yeah, that's still way too vague. I'm not sure how to really specify this in a manner that's both unambiguous and clear. Any suggestions?) I am not 100% sure that this is what you are trying to say, but how about this: The transform that is current when the path is closed applies to the entire path.
Re: [whatwg] Canvas arcTo method
On Mon, 20 Aug 2012, Michael Day wrote: The camvas arcTo method generates an arc that touches two tangent lines. The first tangent line is from the last point in the previous subpath to the first point passed to the arcTo method. What happens in this situation: ctx.lineTo(100, 100); ctx.scale(2, 1); ctx.arcTo(100, 100, 100, 200, 100); The current transformation matrix should be used to transform the generated arc, not to transform its control points. The intent is that the whole thing be done in the transformed coordinate space. The spec was rather poorly written, I've made it slightly better (though only minimally so... I'm not really sure how to write the spec to be both clear and accurate). On Tue, 21 Aug 2012, Michael Day wrote: For arcTo, it's much less obvious how the arc should be generated from the three control points, when the first control point is transformed by a different matrix to the last two; in this case you cannot just remember the three points in absolute canvas coordinates, but the specification does not clarify this. Does it work if you just transform all the points and the line? (Yeah, that's still way too vague. I'm not sure how to really specify this in a manner that's both unambiguous and clear. Any suggestions?) On Tue, 21 Aug 2012, Michael Day wrote: You cannot transform the three control points, and then generate the arc. If you do this, you will always get circular arcs, whereas a scale(2, 1) will produce an elliptical arc. You have to generate the arc, then scale it. Yeah, that's why the spec hand-waves to transform the line too... but I agree that that doesn't really work. Do you have any suggestion of how to spec this better? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Canvas arcTo method
Hi Michael, in your case, the first control point is not the same as the last point of the subpath. The 'scale(2,1)' set up a different coordinate system. You can rewrite your code from this: ctx.lineTo(100, 100); ctx.scale(2, 1); ctx.arcTo(100, 100, 100, 200, 100); to this: ctx.scale(2, 1); *ctx.lineTo(50, 100);* ctx.arcTo(100, 100, 100, 200, 100); Rik PS Doing the following doesn't' seem to work on chrome and ie9 because they didn't implement the second radius parameter: ctx.lineTo(100, 100); ctx.arcTo(200, 100, 200, 200, 200, 100); On Sun, Aug 19, 2012 at 8:10 PM, Michael Day mike...@yeslogic.com wrote: Hi, The camvas arcTo method generates an arc that touches two tangent lines. The first tangent line is from the last point in the previous subpath to the first point passed to the arcTo method. What happens in this situation: ctx.lineTo(100, 100); ctx.scale(2, 1); ctx.arcTo(100, 100, 100, 200, 100); The current transformation matrix should be used to transform the generated arc, not to transform its control points. However, in this case the first untransformed control point is equal to the last point in the previous subpath, which means it must generate a straight line and not an arc. Firefox and Chrome do not do this, as can be seen by viewing the attached HTML file. What is the correct behaviour in this case? Best regards, Michael
Re: [whatwg] Canvas arcTo method
Hi Rik, The 'scale(2,1)' set up a different coordinate system. You can rewrite your code from this: ctx.lineTo(100, 100); ctx.scale(2, 1); ctx.arcTo(100, 100, 100, 200, 100); to this: ctx.scale(2, 1); *ctx.lineTo(50, 100);* ctx.arcTo(100, 100, 100, 200, 100); Right, these will produce the same arc. But how should this be implemented in the user agent? It's almost like it is getting the last point in the previous subpath, transforming it by the inverse of the current transformation matrix, generating the arc, and then transforming the arc by the matrix. Is this what Firefox and Chrome do? There is no hint of this in the spec, which is quite ambiguous about how the current transform should affect previous subpaths. Cheers, Michael
Re: [whatwg] Canvas arcTo method
On Mon, Aug 20, 2012 at 5:55 PM, Michael Day mike...@yeslogic.com wrote: Hi Rik, The 'scale(2,1)' set up a different coordinate system. You can rewrite your code from this: ctx.lineTo(100, 100); ctx.scale(2, 1); ctx.arcTo(100, 100, 100, 200, 100); to this: ctx.scale(2, 1); *ctx.lineTo(50, 100);* ctx.arcTo(100, 100, 100, 200, 100); Right, these will produce the same arc. But how should this be implemented in the user agent? It's almost like it is getting the last point in the previous subpath, transforming it by the inverse of the current transformation matrix, generating the arc, and then transforming the arc by the matrix. Yes, that is one way of implementing it. This is not specific to arcTo; this happens with all drawing operators. Is this what Firefox and Chrome do? There is no hint of this in the spec, which is quite ambiguous about how the current transform should affect previous subpaths. I don't know. It just depends how they implemented in. They might apply the CTM to all the coordinates or keep the coordinates and pass them along with the CTM to the drawing system.
Re: [whatwg] Canvas arcTo method
Hi Rik, Yes, that is one way of implementing it. This is not specific to arcTo; this happens with all drawing operators. It is not quite the same with other drawing operators, for example: ctx.setTransform(...T1...); ctx.lineTo(100, 100); ctx.setTransform(...T2...); ctx.lineTo(100, 100); This will draw a line from T1*(100,100) to T2*(100,100), and these points can be calculated immediately in absolute canvas coordinates, there is no need to apply any inverse transformations. For arcTo, it's much less obvious how the arc should be generated from the three control points, when the first control point is transformed by a different matrix to the last two; in this case you cannot just remember the three points in absolute canvas coordinates, but the specification does not clarify this. I don't know. It just depends how they implemented in. They might apply the CTM to all the coordinates or keep the coordinates and pass them along with the CTM to the drawing system. In our case we are rendering to PDF, which cannot change the transformation matrix halfway through a path. Even if it could, it does not support arc primitives. But anyway, regardless of the exact details of how the browsers implement it, there is the question of how to describe the algorithm to someone such that it can be implemented with pencil and paper. Currently it is very non-obvious how arcTo should work when a new transform has been applied since the last drawing command. Best regards, Michael
Re: [whatwg] Canvas arcTo method
On Mon, Aug 20, 2012 at 8:15 PM, Michael Day mike...@yeslogic.com wrote: Hi Rik, Yes, that is one way of implementing it. This is not specific to arcTo; this happens with all drawing operators. It is not quite the same with other drawing operators, for example: ctx.setTransform(...T1...); ctx.lineTo(100, 100); ctx.setTransform(...T2...); ctx.lineTo(100, 100); This will draw a line from T1*(100,100) to T2*(100,100), and these points can be calculated immediately in absolute canvas coordinates, there is no need to apply any inverse transformations. For arcTo, it's much less obvious how the arc should be generated from the three control points, when the first control point is transformed by a different matrix to the last two; in this case you cannot just remember the three points in absolute canvas coordinates, but the specification does not clarify this. Yes you can go to absolute canvas coordinates but you need to remember that the radius is transformed too. I don't know. It just depends how they implemented in. They might apply the CTM to all the coordinates or keep the coordinates and pass them along with the CTM to the drawing system. In our case we are rendering to PDF, which cannot change the transformation matrix halfway through a path. I am sure that it's supposed to work. Do you have an example where this is not the case? (Maybe you're using PDFL?) Even if it could, it does not support arc primitives. But anyway, regardless of the exact details of how the browsers implement it, there is the question of how to describe the algorithm to someone such that it can be implemented with pencil and paper. Currently it is very non-obvious how arcTo should work when a new transform has been applied since the last drawing command. Best regards, Michael
Re: [whatwg] Canvas arcTo method
Hi Rik, Yes you can go to absolute canvas coordinates but you need to remember that the radius is transformed too. You cannot transform the three control points, and then generate the arc. If you do this, you will always get circular arcs, whereas a scale(2, 1) will produce an elliptical arc. You have to generate the arc, then scale it. I am sure that it's supposed to work. Do you have an example where this is not the case? (Maybe you're using PDFL?) This is getting off-topic, but in the PDF 1.7 specification, section 4.1 Graphics Objects, it states that inside a path object the only allowed operators are the path construction operators, followed by the path painting operators. This does not include page description level operators that change the graphics state, such as the transformation. Cheers, Michael
[whatwg] Canvas arcTo method
Hi, The camvas arcTo method generates an arc that touches two tangent lines. The first tangent line is from the last point in the previous subpath to the first point passed to the arcTo method. What happens in this situation: ctx.lineTo(100, 100); ctx.scale(2, 1); ctx.arcTo(100, 100, 100, 200, 100); The current transformation matrix should be used to transform the generated arc, not to transform its control points. However, in this case the first untransformed control point is equal to the last point in the previous subpath, which means it must generate a straight line and not an arc. Firefox and Chrome do not do this, as can be seen by viewing the attached HTML file. What is the correct behaviour in this case? Best regards, Michael
Re: [whatwg] Canvas arcTo method
Firefox and Chrome do not do this, as can be seen by viewing the attached HTML file. Or since attachments are stripped, here is the file: http://www.princexml.com/arcto.html Cheers, Michael
Re: [whatwg] Canvas arcTo all points on a line
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
Re: [whatwg] Canvas arcTo all points on a line
On Sat, Dec 27, 2008 at 9:37 AM, Dirk Schulze vb...@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 exc...@gmail.com
Re: [whatwg] Canvas arcTo all points on a line
Philip Taylor ha scritto: 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. 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). WBR, Alex -- Caselle da 1GB, trasmetti allegati fino a 3GB e in piu' IMAP, POP3 e SMTP autenticato? GRATIS solo con Email.it http://www.email.it/f Sponsor: Con Danone Activia, puoi vincere cellulari Nokia e Macbook Air. Scopri come Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=8549d=21-1
Re: [whatwg] Canvas arcTo all points on a line
On Wed, Jan 21, 2009 at 2:45 PM, Philip Taylor excors+wha...@gmail.com wrote: On Sat, Dec 27, 2008 at 9:37 AM, Dirk Schulze vb...@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. [...] 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. -- Philip Taylor exc...@gmail.com
[whatwg] Canvas arcTo all points on a line
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. 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. thanks Dirk
Re: [whatwg] Canvas arcTo all points on a line
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). Please correct me if I missunderstood the specification. Dirk Am Samstag, den 27.12.2008, 10:37 +0100 schrieb Dirk Schulze: 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. 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. thanks Dirk
Re: [whatwg] Canvas arcTo
On 31/01/2008, Ian Hickson [EMAIL PROTECTED] wrote: On Mon, 2 Jul 2007, Philip Taylor wrote: If the point (x2, y2) is on the line defined by the points (x0, y0) and (x1, y1) then the method must do nothing, as no arc would satisfy the above constraints. - why would no arc satisfy the constraints? If P0, P1, P2 are collinear and non-coincident, then (I think) any of the (infinitely many) circles which have the given radius and touch tangential to the line P0-P2 will satisfy the constraints (i.e. being tangential to P0-P1 at some point and to P1-P2 at some point). The idea is to just take the two (infinite) lines that are defined by the points (end at P1, cross P0 and P2), and draw a circle with the given radius between them. When the lines are the same line (i.e. P0-P1 is parallel to P1-P2) then no circle with a finite non-zero radius can touch the line tangentially at more than two points, since for each half of the circle, every point has a different tangent, and the two points on opposite sides of the circle are tangents to parallel but distinct lines unless the radius is zero. No? The circle can't touch tangentially at two distinct points, but nothing said there had to be two distinct points. There just had to be one point on the circle tangential to one line, and one point tangential to the other line, so they could easily be equal points. About the updated specification: the method must add a point (xinf;, yinf;) - s/inf;/infin;/ the infinite line that crosses the point (x0, y0) and ends at the point (x1, y1) - it could be clearer to say half-infinite line. (It seems the technical term is ray or half-line, but those aren't as clear.) -- Philip Taylor [EMAIL PROTECTED]
Re: [whatwg] Canvas arcTo
On Sat, 2 Feb 2008, Philip Taylor wrote: The circle can't touch tangentially at two distinct points, but nothing said there had to be two distinct points. IIRC it used to say another point. It's certainly more explicitly now. About the updated specification: the method must add a point (xinf;, yinf;) - s/inf;/infin;/ the infinite line that crosses the point (x0, y0) and ends at the point (x1, y1) - it could be clearer to say half-infinite line. (It seems the technical term is ray or half-line, but those aren't as clear.) Fixed. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Canvas arcTo
On Mon, 2 Jul 2007, Philip Taylor wrote: As implemented, the operation of arcTo in Firefox (2, 3) and Opera (9.2, 9.5) is utterly unrelated to the spec and arguably crazy. At least Opera has the right spirit and tries drawing arcs between points, though they're the wrong points and they're always semicircles. Safari nearly matches the spec, and it's still sensible when it disagrees with the spec, so that's the only one that's relevant to consider. There are some examples at http://canvex.lazyilluminati.com/misc/arcto.html. If the point (x2, y2) is on the line defined by the points (x0, y0) and (x1, y1) then the method must do nothing, as no arc would satisfy the above constraints. - why would no arc satisfy the constraints? If P0, P1, P2 are collinear and non-coincident, then (I think) any of the (infinitely many) circles which have the given radius and touch tangential to the line P0-P2 will satisfy the constraints (i.e. being tangential to P0-P1 at some point and to P1-P2 at some point). The idea is to just take the two (infinite) lines that are defined by the points (end at P1, cross P0 and P2), and draw a circle with the given radius between them. When the lines are the same line (i.e. P0-P1 is parallel to P1-P2) then no circle with a finite non-zero radius can touch the line tangentially at more than two points, since for each half of the circle, every point has a different tangent, and the two points on opposite sides of the circle are tangents to parallel but distinct lines unless the radius is zero. No? When P0-P1 and P1-P2 are parallel and the same direction, Safari just draws the line P0-P1. When they are parallel but opposing directions, it instead draws a line from P0 to a point infinitely far from P0 in the direction P1-P2. That is sensible in both cases since it's equal to the limit as the two lines tend towards parallelism. Indeed. I've required this now. If P0=P1 (and either P2=P1 or P2!=P1) then Safari does nothing at all and does not add any points to the subpath (or, equivalently, it does add the point P1 to the subpath, which has no effect since the line P0-P1 has zero length). If P1=P2 and P0!=P1, then it adds the point P1 to the subpath. Both of these seem generally sane - there's no sensible limit as the points tend towards coincidence, so there's no real correct answer, and drawing the straight line P0-P1 seems an adequate thing to do. Ok, done. Negative or zero values for radius must cause the implementation to raise an INDEX_SIZE_ERR exception. - why not allow zero? You just get an arc at P1 with zero length, with the start and end tangent points both at P1, so the effect would be a straight line from P0 to P1, without needing to handle it as a special case. Safari works like that. Done. So, I think the following definition would cover all the cases and match Safari: [...] (BTW, it's actually easier for me to end up rewriting the text in response to feedback, than it is for me to handle suggested replacement text. One major reason for this is that if the text has been changed in response to other feedback, I risk losing those changes if I just replace it.) Cheers, -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Canvas arcTo
Which straight line do you mean? In the first case, the constraints are: * There is a circle with the given radius. * The infinite line P0-P1 is tangential to that circle. * The infinite line P1-P2 is tangential to that circle. * The Arc is the shortest arc of that circle, between the points where the circle touches the two lines. When P0-P1-P2 is a straight line, there is a circle (among many others) which satisfies the first three constraints, and there is a zero-length arc of that circle which satisfies the fourth constraint. (You can't then re-calculate the circle's radius from the arc, because the arc is just a single point, but I don't think that means the arc doesn't exist as part of a finite circle). That's not very useful when you want to draw stuff since there are infinitely many distinct things you could draw, but it's not the case that there's nothing you could draw. In the second case, there is one distinct circle (with zero radius) which touches both the lines, and there is one distinct point which the start and end tangent points must be equal to, and the shortest arc which joins those two points has zero length. There's still infinitely many such arcs and it gets a bit confusing if you want to work out its direction (in order to draw line joins and caps), but you'd always be drawing at least a line from P0 to P1. (To handle that confusion about the zero-sized arc, I think my earlier suggestion should be modified to say ... Otherwise, if x1=x2 and y1=y2, or if the line defined by the points (x0, y0) and (x1, y1) is parallel and in the same direction as the line defined by the points (x1, y1) and (x2, y2), ** or if radius is zero, ** then the method must connect the point (x0, y0) to the point (x1, y1) by a straight line and add the point (x1, y1) to the subpath. ...) Actually, I just realised there's still a problem in the normal non-parallel non-zero-size case, because there are four different circles which have the two infinite lines as tangents. (And you have to use infinite lines rather than finite lines, to handle the second case in http://canvex.lazyilluminati.com/misc/arcto.html like Safari). So I think it would have to say something like: Otherwise, let L01 be the line through the points (x0, y0) and (x1, y1), and let L12 be the line through the points (x1, y1) and (x2, y2). Consider the circle that has L01 and L12 as tangents, and has its origin and the point (x2, y2) on the same side of L01, and has its origin and the point (x0, y0) on the same side of L12, and has radius radius. The points at which this circle touches these two lines are called the start and end tangent points respectively. Let The Arc be the shortest arc given by the circumference of this circle, joining the start and end tangent points. unless I got anything else wrong. On 03/07/07, Kristof Zelechovski [EMAIL PROTECTED] wrote: The questioned wording is correct: a straight line has infinite radius and thus does not match the requirement if the radius is finite. Chris -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Philip Taylor Sent: Monday, July 02, 2007 1:42 PM To: WHATWG Subject: [whatwg] Canvas arcTo If the point (x2, y2) is on the line defined by the points (x0, y0) and (x1, y1) then the method must do nothing, as no arc would satisfy the above constraints. - why would no arc satisfy the constraints? If P0, P1, P2 are collinear and non-coincident, then (I think) any of the (infinitely many) circles which have the given radius and touch tangential to the line P0-P2 will satisfy the constraints (i.e. being tangential to P0-P1 at some point and to P1-P2 at some point). [snip] Negative or zero values for radius must cause the implementation to raise an INDEX_SIZE_ERR exception. - why not allow zero? You just get an arc at P1 with zero length, with the start and end tangent points both at P1, so the effect would be a straight line from P0 to P1, without needing to handle it as a special case. Safari works like that. -- Philip Taylor [EMAIL PROTECTED]
[whatwg] Canvas arcTo
As implemented, the operation of arcTo in Firefox (2, 3) and Opera (9.2, 9.5) is utterly unrelated to the spec and arguably crazy. At least Opera has the right spirit and tries drawing arcs between points, though they're the wrong points and they're always semicircles. Safari nearly matches the spec, and it's still sensible when it disagrees with the spec, so that's the only one that's relevant to consider. There are some examples at http://canvex.lazyilluminati.com/misc/arcto.html. If the point (x2, y2) is on the line defined by the points (x0, y0) and (x1, y1) then the method must do nothing, as no arc would satisfy the above constraints. - why would no arc satisfy the constraints? If P0, P1, P2 are collinear and non-coincident, then (I think) any of the (infinitely many) circles which have the given radius and touch tangential to the line P0-P2 will satisfy the constraints (i.e. being tangential to P0-P1 at some point and to P1-P2 at some point). When P0-P1 and P1-P2 are parallel and the same direction, Safari just draws the line P0-P1. When they are parallel but opposing directions, it instead draws a line from P0 to a point infinitely far from P0 in the direction P1-P2. That is sensible in both cases since it's equal to the limit as the two lines tend towards parallelism. If P0=P1 (and either P2=P1 or P2!=P1) then Safari does nothing at all and does not add any points to the subpath (or, equivalently, it does add the point P1 to the subpath, which has no effect since the line P0-P1 has zero length). If P1=P2 and P0!=P1, then it adds the point P1 to the subpath. Both of these seem generally sane - there's no sensible limit as the points tend towards coincidence, so there's no real correct answer, and drawing the straight line P0-P1 seems an adequate thing to do. Negative or zero values for radius must cause the implementation to raise an INDEX_SIZE_ERR exception. - why not allow zero? You just get an arc at P1 with zero length, with the start and end tangent points both at P1, so the effect would be a straight line from P0 to P1, without needing to handle it as a special case. Safari works like that. So, I think the following definition would cover all the cases and match Safari: The arcTo(x1, y1, x2, y2, radius) method must do nothing if the context has no subpaths. If the context does have a subpath, then the behaviour depends on the arguments and the last point in the subpath. Let the point (x0, y0) be the last point in the subpath. If x0=x1 and y0=y1, then the method must do nothing. Otherwise, if x1=x2 and y1=y2, or if the line defined by the points (x0, y0) and (x1, y1) is parallel and in the same direction as the line defined by the points (x1, y1) and (x2, y2), then the method must connect the point (x0, y0) to the point (x1, y1) by a straight line and add the point (x1, y1) to the subpath. Otherwise, if the line defined by the points (x0, y0) and (x1, y1) is parallel and in the opposite direction to the line defined by the points (x1, y1) and (x2, y2), then the method must connect the point (x0, y0) to the point obtained by extending an infinite distance from (x0, y0) in the direction of the line defined by (x1, y1) and (x2, y2), and add that new point to the subpath. Otherwise, let The Arc be the shortest arc given by the circumference of the circle that has one point tangent to the line defined by the points (x0, y0) and (x1, y1), another point tangent to the line defined by the points (x1, y1) and (x2, y2), and that has radius radius. The points at which this circle touches these two lines are called the start and end tangent points respectively. The method must connect the point (x0, y0) to the start tangent point by a straight line, then connect the start tangent point to the end tangent point by The Arc, and finally add the start and end tangent points to the subpath. Negative values for radius must cause the implementation to raise an INDEX_SIZE_ERR exception. -- Philip Taylor [EMAIL PROTECTED]
Re: [whatwg] Canvas arcTo
The questioned wording is correct: a straight line has infinite radius and thus does not match the requirement if the radius is finite. Chris -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Philip Taylor Sent: Monday, July 02, 2007 1:42 PM To: WHATWG Subject: [whatwg] Canvas arcTo If the point (x2, y2) is on the line defined by the points (x0, y0) and (x1, y1) then the method must do nothing, as no arc would satisfy the above constraints. - why would no arc satisfy the constraints? If P0, P1, P2 are collinear and non-coincident, then (I think) any of the (infinitely many) circles which have the given radius and touch tangential to the line P0-P2 will satisfy the constraints (i.e. being tangential to P0-P1 at some point and to P1-P2 at some point). [snip] Negative or zero values for radius must cause the implementation to raise an INDEX_SIZE_ERR exception. - why not allow zero? You just get an arc at P1 with zero length, with the start and end tangent points both at P1, so the effect would be a straight line from P0 to P1, without needing to handle it as a special case. Safari works like that.