## pyx-user

 [PyX-user] connect.arc bug From: Francisco Borges - 2005-09-06 16:15:50 Attachments: connect_angle.py Hello, This is a rather pathological problem and its easily solvable setting relangle=1 but still it's worth taking a look. -------------- Setting connect.arc's argument relangle to zero on two boxes *not* on the self height, leads to well, surprising effects. It's also worth noting the different in length of arc(,, relangle=0) and line(), when the boxes are at the same height and using the same boxdists. Check the attached colorful ;-) example. Cheers, -- Francisco Borges Alfa Informatica - RuG 
 Re: [PyX-user] connect.arc bug From: Michael Schindler - 2005-09-06 16:59:29 Hello Francisco, > Check the attached colorful ;-) example. well, the result looks nice, but to me this looks not like a bug but like a user's mis-use of the parameters. You use j2 = (2,-1.5,r"$\theta = 0$", 0, color.rgb.green) ^ relangle c.stroke(arc(t0, t, boxdists=.2, relangle=j[3]), [j[4], deco.earrow.normal]) In your example you set the relative angle for the arc connectors to 0. This is the angle between the straight lines connecting the box centers and the connecting arc. If you set this to zero, you ask for an arc with infinite radius. In your example something like 1e+17. Of course, this arc cannot be safely intersected with the boxes' surrounding paths. If you set this angle to 1 degree, everything works fine. j2 = (2,-1.5,r"$\theta = 0$", 1, color.rgb.green) Michael. P.S: For a nice outcome consider using [text.vshift.mathaxis, text.halign.center] for the text. Then, the reference point of the connecting box will be in the middle of the text ;-) -- "A mathematician is a device for turning coffee into theorems" Paul Erdös. 
 Re: [PyX-user] connect.arc bug From: Francisco Borges - 2005-09-07 11:07:03 Hello Michael, =BB On Tue, Sep 06, 2005 at 06:59PM +0200, Michael Schindler wrote: > > Check the attached colorful ;-) example. > > well, the result looks nice, but to me this looks not like a bug but > like a user's mis-use of the parameters. I beg to differ :-) > In your example you set the relative angle for the arc connectors to > 0. This is the angle between the straight lines connecting the box > centers and the connecting arc. If you set this to zero, you ask for > an arc with infinite radius. In your example something like 1e+17. Of > course, this arc cannot be safely intersected with the boxes' > surrounding paths. The infinite radius comes because that's how far you would have to push it to get a 0 angled arc, no discussion here. But since we know that that means a straight line and that somebody wants to draw this arc(,,relangle=3D0), why shouldn't the call deliver that: a straight line between the boxes? See the attached file, you have to acknowledge that the least surprising result for the "blue" group when relangle=3D0, is to have a line drawn in the middle of the surrounding ones. Which is what one gets, due to a lucky coincidence I now think, if the boxes are on the same height but not otherwise. If you still think that relangle=3D0 is user misuse of the parameters, an= d I hope you don't, that should be documented in the manual and relangle=3D= 0 should best be left disabled for arc. > P.S: For a nice outcome consider using > [text.vshift.mathaxis, text.halign.center] > for the text. Then, the reference point of the connecting box will be > in the middle of the text ;-) Thanks for the tip, the outcome does get better. Cheers, Francisco 
 Re: [PyX-user] connect.arc bug From: Francisco Borges - 2005-09-07 16:14:37 =BB On Wed, Sep 07, 2005 at 04:43PM +0200, Michael Schindler wrote: > Hello Francisco, > > unfortunately, your attachment got lost on the way through a > spam filter? Would you send it to me again? No, I just checked... I didn't attach the file. Sorry. I'm simply including it this time... Francisco #=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D #! /usr/bin/env python # -*- coding:iso-8859-15 -*- # Time-stamp: from pyx import * from pyx.connector import arc, line c =3D canvas.canvas() j1 =3D (0, 0, r"$\alpha\beta$", None, color.rgb.black) j3 =3D (5, 0, r"$\theta$", 0, color.rgb.red) j4 =3D (5, 5, r"$\theta$", -5, color.rgb.blue) for j in [j1, j3, j4]: t =3D text.text(j[0],j[1],j[2], [j[4], text.vshift.mathaxis, text.hal= ign.center]) c.insert(t) if j !=3D j1: for k in range(-15,18,3): c.stroke(arc(t0, t, boxdists=3D.1, relangle=3Dk), [style.line= width.THIN]) else: t0 =3D t c.writeEPSfile(__file__[:-3]) c.writePDFfile(__file__[:-3]) 
 Re: [PyX-user] connect.arc bug From: Andre Wobst - 2005-09-07 17:48:44 Hi, On 07.09.05, Francisco Borges wrote: > If you still think that relangle=0 is user misuse of the parameters, and > I hope you don't, that should be documented in the manual and relangle=0 > should best be left disabled for arc. I see your point especially for the second example. Still, I support Michaels point of view, that an arc connector should return an arc and nothing else. You can't describe a straight line by an arc, so you're just requesting the wrong thing. The arc connector is just not welldefined for a relangle of zero. In case we want to replace the arc by a straight line, the question arrises when to do that. What do you think would be an appropriate threshould? How to define that threshold (do we need an parameter for that ... what should this parameter look like)? I just don't know ... and that's again an indication, that it might not be right to do fancy things. What do you suggest? André -- by _ _ _ Dr. André Wobst / \ \ / ) wobsta@..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ 
 Re: [PyX-user] connect.arc bug From: Francisco Borges - 2005-09-07 19:39:59 Hello, =BB On Wed, Sep 07, 2005 at 07:48PM +0200, Andre Wobst wrote: > nothing else. You can't describe a straight line by an arc, so you're > just requesting the wrong thing. The arc connector is just not > welldefined for a relangle of zero. I see the point. But if that should be the case, I would suggest adding something to the documentation for the sloppy users like me. > In case we want to replace the arc by a straight line, the question > arrises when to do that. What do you think would be an appropriate > threshould? How to define that threshold (do we need an parameter for > that ... what should this parameter look like)? I just don't know ... IMHO a reasonable threshold would be: if relangle =3D=3D 0.: # make it a straight line. But there is more to it, see below. > and that's again an indication, that it might not be right to do fancy > things. What do you suggest? First I would suggest you to look again at these try/except blocks: At pyx/connector.py,=20 class arc_pt(connector_pt): def __init__(self, box1, box2, relangle=3D45, absbulge=3DNone, relbulge=3DNone, boxdists=3D[0,0]): [....] if relbulge is not None or absbulge is not None: try: radius =3D abs(0.5 * (bulge + 0.25 * distance**2 / bulge)) except: radius =3D 10 * distance # default value for too straight ar= cs radius =3D min(radius, 10 * distance) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # ad hoc threshold. [.....] # otherwise use relangle [...] bulge=3DNone try: radius =3D 0.5 * distance / abs(cos(0.5*math.pi - radians(relang= le))) except: radius =3D 10 * distance ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # this one will not be triggered (i think). try: center =3D tan(0.5*math.pi - radians(relangle)) except: center =3D 0 =20 I can only guess about the intention of these try/except clauses, and my guess is that they are here to get a ZeroDivisionError. /If/ that's the case... I would tell you that: math.cos is not precise enough to raise th= at for 1/math.cos(pi/2) (or math.tan(pi/2)).=20 So in any case, you should check the size of radius or center with the same threhold as in the "relbulge !=3D None" part. (where an ad hoc thres= hold is in use ;-)). My suggestion would be to whenever hitting this huge radius threshold (currently 10*distance, if you use relbulge), instead of setting radius t= o some huge value (i.e. 10*distance), switch to a straight line. This would cover the relangle=3D=3D0 case and also the cases where relangle$\approx$= 0. This could be better than just checking for relangle=3D=3D0. It's not perfect, I know, but it seems like a better compromise: it would output a usable figure while setting radius=3D10*distance doesn't seems t= o. Cheers, Francisco. 
 Re: [PyX-user] connect.arc bug From: Andre Wobst - 2005-09-07 20:15:48 Hi, On 07.09.05, Francisco Borges wrote: > I see the point. But if that should be the case, I would suggest adding > something to the documentation for the sloppy users like me. I guess this will not avoid stepping into that problem. In that sense a "just document it" solution is not really good either. > > In case we want to replace the arc by a straight line, the question > > arrises when to do that. What do you think would be an appropriate > > threshould? How to define that threshold (do we need an parameter for > > that ... what should this parameter look like)? I just don't know ... > > IMHO a reasonable threshold would be: > > if relangle == 0.: > # make it a straight line. I would not like that. Our instabilities are of a differnt kind. In some sense they occure for an arc segment of a very small angle and a huge size. In a recent discussion of the stability of a circle we needed to allow for some very small straight lines (replacing a 0.1 degree part of the full circle). Maybe this is something similar. > First I would suggest you to look again at these try/except blocks: I totally agree with you that the try-except-blocks are just plain wrong. BTW I was not aware of the 10*distance radius feature, which I would like to call a misfeature. But they guide us to a possibly solution: > So in any case, you should check the size of radius or center with the > same threhold as in the "relbulge != None" part. (where an ad hoc threshold > is in use ;-)). > > My suggestion would be to whenever hitting this huge radius threshold > (currently 10*distance, if you use relbulge), instead of setting radius to > some huge value (i.e. 10*distance), switch to a straight line. This would > cover the relangle==0 case and also the cases where relangle$\approx$0. This > could be better than just checking for relangle==0. > > It's not perfect, I know, but it seems like a better compromise: it would > output a usable figure while setting radius=10*distance doesn't seems to. But to take the whole picture wouldn't that be equivalent to having a threshold for the relangle. It seems to. And overall I agree with you that we should not even try to draw some arcs with a center that far away from the almost straight line we want to draw. So the argument, that the radius should not become too big sounds right. But this turns into a threshould for the relangle and we should not even start with the (unstable) arc calculation. So Michael, remember that other circle path problem and our solution there? We agreed on replacing small args by straight lines that time, since it is not visible. The point there was different: we always just substituted a very small part of the whole circle ... so our error was always small compared to the full object. Here I'm still not sure whether its right to replace the arc by a line. But in some other sense it seems to be similar ... I'm starting to get convinced to remove this instability by some threshold and be all set ... André -- by _ _ _ Dr. André Wobst / \ \ / ) wobsta@..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ 
 Re: [PyX-user] connect.arc bug From: Michael Schindler - 2005-09-08 07:42:42 Hello, On 07.09.05, Andre Wobst wrote: > On 07.09.05, Francisco Borges wrote: > > > > In case we want to replace the arc by a straight line, the question > > > arrises when to do that. What do you think would be an appropriate > > > threshould? How to define that threshold (do we need an parameter for > > > that ... what should this parameter look like)? I just don't know ... > In a recent discussion of the stability of a circle we needed to allow > for some very small straight lines (replacing a 0.1 degree part of the > full circle). Maybe this is something similar. This was a different story. There, everything was well-defined, and the problems were caused by rounding errors (the beginning and the ending of the circle did not match). Here, we try to draw and arc that has -- in principe -- infinite radius. This can never be done. > > First I would suggest you to look again at these try/except blocks: > > I totally agree with you that the try-except-blocks are just plain > wrong. BTW I was not aware of the 10*distance radius feature, which I > would like to call a misfeature. Right. This is very old code, from the times when I started to write code in Python. These (and others) clearly have to be removed. > > So in any case, you should check the size of radius or center with the > > same threhold as in the "relbulge != None" part. (where an ad hoc threshold > > is in use ;-)). What I have learned from you and Jörg is that excessive input-checking is not very "pythonic". This was what you said when first looking at this connector code. > > My suggestion would be to whenever hitting this huge radius threshold > > (currently 10*distance, if you use relbulge), instead of setting radius to > > some huge value (i.e. 10*distance), switch to a straight line. This would > > cover the relangle==0 case and also the cases where relangle$\approx$0. This > > could be better than just checking for relangle==0. > > > > It's not perfect, I know, but it seems like a better compromise: it would > > output a usable figure while setting radius=10*distance doesn't seems to. Well, at this point the code was really wrong: The radius=10*distance cannot be executed -- simply not possible. > So Michael, remember that other circle > path problem and our solution there? We agreed on replacing small args > by straight lines that time, since it is not visible. > The point there > was different: we always just substituted a very small part of the > whole circle ... so our error was always small compared to the full > object. Here I'm still not sure whether its right to replace the arc > by a line. But in some other sense it seems to be similar ... Yes, it was a totally different story. There, we always returned a full circle, and in that case we know what the user wants: A full circle. In this case, the user asks for an arc and wants a straight line. This is the problem. > I'm starting to get convinced to remove this instability by some > threshold and be all set ... An additional parameter for the arc connector is not much effort. But what should it be? Something like the maximal radius or the minimal relangle. Instead of a line I would then rather return a straight curve connector, because the arc connector is converted into normcurves anyhow. Michael. -- "A mathematician is a device for turning coffee into theorems" Paul Erdös. 
 Re: [PyX-user] connect.arc bug From: Joerg Lehmann - 2005-09-08 08:44:08 Hi Michael! On 08.09.05, Michael Schindler wrote: [ snip ] > An additional parameter for the arc connector is not much effort. But > what should it be? Something like the maximal radius or the minimal > relangle. At first, I would have said: radius/length of connector. This quantity is dimensionless and is the relevant thing from a visual point of view. Since it is related to relangle in some way, I would recommend using a minimal relangle. Btw, the idea of falling back to a straight line, which geometrically can be considered as a degenerate circle anyway, seems to be The Right Thing (tm) to me. Jörg 
 Re: [PyX-user] connect.arc bug From: Andre Wobst - 2005-09-08 09:13:26 Hi, On 08.09.05, Joerg Lehmann wrote: > At first, I would have said: radius/length of connector. This quantity > is dimensionless and is the relevant thing from a visual point of view. > Since it is related to relangle in some way, I would recommend using a > minimal relangle. > > Btw, the idea of falling back to a straight line, which geometrically > can be considered as a degenerate circle anyway, seems to be The Right > Thing (tm) to me. +1 André -- by _ _ _ Dr. André Wobst / \ \ / ) wobsta@..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ 
 Re: [PyX-user] connect.arc bug From: Andre Wobst - 2005-09-08 09:20:29 Hi, On 08.09.05, Michael Schindler wrote: > What I have learned from you and Jörg is that excessive input-checking > is not very "pythonic". This was what you said when first looking at > this connector code. Overall that's right. To make an excessive example: You should not try to convert an string into an int, just because you want to start calculations. > Yes, it was a totally different story. There, we always returned a > full circle, and in that case we know what the user wants: A full > circle. In this case, the user asks for an arc and wants a straight > line. This is the problem. Right. But in principle the problem is still well-defined. Just the solution can not be described by an arc anymore. And the numerics for the arc gets instable ... > > I'm starting to get convinced to remove this instability by some > > threshold and be all set ... > > An additional parameter for the arc connector is not much effort. But > what should it be? Something like the maximal radius or the minimal > relangle. Instead of a line I would then rather return a straight > curve connector, because the arc connector is converted into > normcurves anyhow. -1 in using a "straigt" curve. André -- by _ _ _ Dr. André Wobst / \ \ / ) wobsta@..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/