[comp.windows.x] Help! My arc has fallen, and it can't get up!

stripes@eng.umd.edu (Joshua Osborne) (06/28/91)

I am trying to draw the outline of a pie wedge.  I (think I) am using the
formula from the Digital Press "X Windows System, C Library and protocall
reference" by Scheifler, Gettys & Newman.  I coded it up like this:

#define RPI (64*180./3.14159)
#define PIPI (3.14159/2)

double ella(a, w, h)
double a;
int w, h;
{
	double skew;

	skew = atan(tan(a) * w/(h+0.0));
	skew += (a < PIPI) ? 0 : (a < 3 * PIPI) ? (2*PIPI) : (4*PIPI);

	return  skew;
}

Then armed with only a filled-out XArc structure, and a semester of Trig 4
years stale, I attempted many variations along the lines of:

v2_pie(xa)
XArc *xa;
{
	XPoint pts[3];
	double s, c;
	int r;

	r = (xa->width + xa->height) / 4;

	pts[1].x = xa->width / 2 + xa->x;
	pts[1].y = xa->height / 2 + xa->y;
	sincos(ella(xa->angle1/RPI, xa->width, xa->height), &s, &c);
	pts[0].x = pts[1].x + xa->width/2 * c;
	pts[0].y = pts[1].y + xa->height/2 * s;
	sincos(ella((xa->angle1+xa->angle2)/RPI, xa->width, xa->height), &s, &c);
	pts[2].x = pts[1].x + xa->width/2 * c;
	pts[2].y = pts[1].y + xa->height/2 * s;

	XSetFillStyle(dpy, drawGC, FillSolid);
	XDrawLines(dpy, win, drawGC, pts, 3, CoordModeOrigin);
	XDrawArcs(dpy, win, drawGC, xa, 1);
	reset_a();
}

I compiled the program, ran it, and it failed.  Miserably.  It's output was
hideous.  Women fainted.  Small children ran away.  Worst of all, the lines
that should have connected the arc endpoints had very little to do with the
arc endpoints.

Does anyone have any suggestions?  How can I compute the xy position of the
arc's endpoints?  Please mail to me; I will summarize any and all replies
to the net.
-- 
           stripes@eng.umd.edu          "Security for Unix is like
      Josh_Osborne@Real_World,The          Multitasking for MS-DOS"
      "The dyslexic porgramer"                  - Kevin Lockwood

mouse@thunder.mcrcim.mcgill.edu (der Mouse) (07/01/91)

In article <1991Jun28.062319.11565@eng.umd.edu>, stripes@eng.umd.edu (Joshua Osborne) writes:

> I am trying to draw the outline of a pie wedge.  I (think I) am using
> the formula from the Digital Press "X Windows System, C Library and
> protocall reference" by Scheifler, Gettys & Newman.

I assume this is the same one that appears in the online Xlib
documentation:

                       |                      width |
   skewed-angle = atan | tan(normal-angle) * ------ | + adjust
                       |                     height |

First, I think you're using it backwards, and second, you shouldn't be
using it.  When you draw the lines, you do

> 	sincos(ella(xa->angle1/RPI, xa->width, xa->height), &s, &c);
> 	pts[0].x = pts[1].x + xa->width/2 * c;
> 	pts[0].y = pts[1].y + xa->height/2 * s;
> 	sincos(ella((xa->angle1+xa->angle2)/RPI, xa->width, xa->height), &s, &c);
> 	pts[2].x = pts[1].x + xa->width/2 * c;
> 	pts[2].y = pts[1].y + xa->height/2 * s;

and the multiplication by width/2 and height/2 is performing the
skewing already.

The formula is used if you want to find the angle the final line makes
on the screen.  That is, if you want to find the angle a such that you
could write

	pts[0].x = pts[1].x + (len * cos(a));
	pts[0].y = pts[1].y + (len * sin(a));

for some len (the computation of which I shall ignore), *then* you want
to call ella.  (Except you don't; you'd want to call the inverse of
ella, which amounts to simply interchanging width and height.)

Of course, if you do keep ella, you really should use atan2 instead of
mucking about with that silly "adjust" thing, which was introduced
simply to allow them to write the function in terms of a mathematical
one-argument atan instead of a computer's two-argument atan2.

There is one other thing wrong: you forgot that you need to write

	pts[0].y = pts[1].y - xa->height/2 * s;

and similarly for pts[2].y, because the angles are measured in a
mathematician's coordinate system on the screen, but the y coordinate
to XDrawLines is measured in a graphics coordinate system - and the y
axes go in opposite directions.

When I fixed the y-axis direction and changed ella to simply return its
first argument, the lines worked just fine for me.

Note that you really should be dividing width and height by 2.0,
because you could lose a pixel in integer division roundoff with what
you have.

> I compiled the program, ran it, and it failed.  Miserably.  It's
> output was hideous.  Women fainted.  Small children ran away.

:-)

> Worst of all, the lines that should have connected the arc endpoints
> had very little to do with the arc endpoints.

I suspect you may have forgotten to #include something crucial.  My
first attempt had similar problems, but once I remembered to #include
<math.h> they went away, and I had only the above two problems.
(Eliminating the tan and atan calls in ella removes the need for
math.h, except that I changed the #defines to use M_PI instead of
3.14159.)

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

stripes@eng.umd.edu (Joshua Osborne) (07/01/91)

In article <1991Jun30.214203.5882@thunder.mcrcim.mcgill.edu> mouse@thunder.mcrcim.mcgill.edu (der Mouse) writes:

Since the (only) answer I got was posted to the net, and correct there will
be no summary.  If the question intrested you read 
<1991Jun30.214203.5882@thunder.mcrcim.mcgill.edu>.

>In article <1991Jun28.062319.11565@eng.umd.edu>, stripes@eng.umd.edu (Joshua Osborne) writes:
>
>> I am trying to draw the outline of a pie wedge.  I (think I) am using
>> the formula from the Digital Press "X Windows System, C Library and
>> protocall reference" by Scheifler, Gettys & Newman.
>
>I assume this is the same one that appears in the online Xlib
>documentation:

Yes.

[...]
>There is one other thing wrong: you forgot that you need to write
>
>	pts[0].y = pts[1].y - xa->height/2 * s;
>
>and similarly for pts[2].y, because the angles are measured in a
>mathematician's coordinate system on the screen, but the y coordinate
>to XDrawLines is measured in a graphics coordinate system - and the y
>axes go in opposite directions.

Ahh!  That was my problem all along (before I even tried the skew-angle
thing...).

>Note that you really should be dividing width and height by 2.0,
>because you could lose a pixel in integer division roundoff with what
>you have.

Mmmm, taken under advisement.  What order does ANSI say promotion is done
for INT/INT*FLOAT?  (INT/INT) to FLOAT, or INT/INT*FLOAT to INT/FLOAT*FLOAT
to FLOAT/FLOAT*FLOAT?  Who cares, I changed 'em all to 2.0.

>> I compiled the program, ran it, and it failed.  Miserably.  It's
>> output was hideous.  Women fainted.  Small children ran away.
>
>:-)

Oh, you laugh!  I bet you wouldn't if you had seen it!

>> Worst of all, the lines that should have connected the arc endpoints
>> had very little to do with the arc endpoints.

>I suspect you may have forgotten to #include something crucial.  My
>first attempt had similar problems, but once I remembered to #include
><math.h> they went away, and I had only the above two problems.

My trig is rusty, not my C.  I had #inc'ed math.h.  I guess I should have
included that in my example 'tho.

>(Eliminating the tan and atan calls in ella removes the need for
>math.h, except that I changed the #defines to use M_PI instead of
>3.14159.)

Hmmm, M_PI.  This is what I get for assuming hand-me-down code does things
right...

Thanks for the help.  The code works now, and as a direct result I've been
promoted, have won the lottery, am constantly hounded by fabulous babes,
and my shirts come back from the laundry whiter than ever.  You win my
infinate gratitude, half the lotto money, second pick of the babes, and
all the cold pizza left in my fridge by the time you come to get your lotto
money (you remember how to get here, right?).

(P.S. the previous paragraph was partly ripped off from Don Hosek, from a
comp.text.tex post)
-- 
           stripes@eng.umd.edu          "Security for Unix is like
      Josh_Osborne@Real_World,The          Multitasking for MS-DOS"
      "The dyslexic porgramer"                  - Kevin Lockwood
"CNN is the only nuclear capable news network..."
    - lbruck@eng.umd.edu (Lewis Bruck)