gEDA-dev: [PATCH] PCB/gtk: Draw rotated arcs correctly
Gabriel Paubert
paubert at iram.es
Tue Apr 17 10:34:38 EDT 2007
On Tue, Apr 17, 2007 at 03:57:37PM +0200, Bernd Jendrissek wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On Tue, Apr 17, 2007 at 12:32:55PM +0200, Peter TB Brett wrote:
> > > > How about something along these lines:
> > > >
> > > > angle = start_angle + 180 % 360;
> > > >
> > > > gdk_draw_arc (gport->drawable, gport->u_gc, 0,
> > > > DRAW_X (cx) - vrx, DRAW_Y (cy) - vry,
> > > > vrx * 2, vry * 2, angle * 64, delta_angle * 64);
> > > >
> > > > This avoids a branch, and requires fewer instructions. OTOH, can
> > > > start_angle be negative?
>
> Cool, as long as my TO3's look right on the screen! (I figured it was
> the HID and not the data structure when I exported the borked footprint
> to gerber and it was fine.)
>
> While I'd be surprised if the '%' operator has any speed advantages, it
> sure is more robust against out-of-range inputs.
The % operator is essentially a division, although division by constants
are handled specially (multiplying to 64 bit by the 2^32/dividend) by
GCC, with some corrections. It makes the code bigger so it is not always
a win (a single cache miss is way more expensive than a few floating
point divides or quare roots today).
Anyway, this is negligible compared to the action of actually drawing an
arc on the screen through the X server.
>
> In my quick search on gdk_draw_arc I didn't see any special mention of
> negative angles, but here is what XDrawArc(3X11) says:
>
> "...and negative angles indicate clockwise motion. If the magnitude of
> angle2 is greater than 360 degrees, XDrawArc or XDrawArcs truncates it
> to 360 degrees."
>
> I don't know if that applies only to the delta or also to the start
> angle.
Only to the delta. The start is modulo 360, any delta higher than 360
would draw a full circle anyway.
But these days most drawing goes through Cairo anyway no?
>
> > > Perhaps a better solution (thinking about it) is to make sure the angle
> > > never over-flows in the first place. Can PCB's internal data-structures
> > > accommodate any necessary range limitation?
>
> While I didn't grok all of PCB's code, it does look like
> RotateArcLowLevel() does limit the range of Arc->StartAngle:
>
> /* add Number*90 degrees to the startangle and check for overflow */
> Arc->StartAngle = (Arc->StartAngle + Number * 90) % 360;
>
> > > You'd then perform the limit wrapping at each load / modification to the
> > > data-structure rather than at draw time. This prevents any internal
> > > overflows too, whilst keeping drawing faster.
> >
> > This seems like a better way of doing it. Fixing at draw time is a bit of a
> > hack.
>
> The HID still has to fix whatever it breaks as a result of coordinate
> transformation; PCB's angular origin is at 9 o'clock whilst GDK and X
> have theirs at 9 o'clock.
Hmm? I believe you mean 3 o'clock for the latter (which I find more
natural myself).
Regards,
Gabriel
More information about the geda-dev
mailing list