From: Daniel Pfeiffer
Subject: sorta Summary: coordinates of an arrowpoint?
Date: 
Message-ID: <PFEIFFER.91Aug29041758@cix.cict.fr>
····@ATHENA.MIT.EDU asked me to summarize:

> ) Given the terminal points of a line (x1,y1) and (x2,y2) is there an
> ) easy (integer if possible) way to figure out the coordinates of a
> ) triangle that forms the point of an arrow?  (Well, I've already
> ) figured out one of them, (x2,y2) :-)  What if the arrow is horizontal
> ) or vertical, i.e.  dx = 0 or dy = 0, this could hurt for divisions?

> No.  Only if BOTH are zero.

> ) The arrowhead need not be perfect, but more pointed than my sketch
> ) suggests, maybe about 15 degrees on each side of the line.
> ) 
> )     (x3,y3)__ (x2,y2)
> )             /|
> )            / (x4,y4)    x3 = ?  y3 = ?
> )           /             x4 = ?  y4 = ?
> )          /
> )         /
> ) (x1,y1)

> To do this exactly not only calls for real arithmetic, but also for
> computing a square root, which may be expensive/complicated.  At the end I
> give some approximation methods that may be useful.  To obtain integer
> arithmetic, you must do some scaling yourself (e.g., multiply everything by
> 10000, and divide the final result again).


> The exact procedure:

> Input: two points (x1,y1) and (x2,y2), the angle phi by which the
> "whiskers" must stand off the "shaft" (e.g., 15 degrees), and the desired
> length L of the whiskers.

> 1.  Compute the distance between (x1,y1) and (x2,y2), which is
>     sqrt((x1-x2)^2 + (y1-y2)^2).  Call it R.

> 2.  Set xx = (L/R)*(x1-x2), yy = (L/R)*(y1-y2).

> 3.  Let c stand for cos(phi), and s for sin(phi).  Then

>     (x3,y3) = (x2 + c*xx + s*yy, y2 - s*xx + c*yy);

>     (x4,y4) = (x2 + c*xx - s*yy, y2 + s*xx + c*yy).


> Approximation for computing the length of a line segment:

> Take the absolute values of the differences of the x-values and of the y-
> values.  Call the smaller A and the larger B.  Compute 0.3978*A + 0.9604*B.
> The result is off by less than 4% from sqrt(A^2 + B^2).

> Example:  A = 5 and B = 12 gives the result 13.5138, while by Pythagoras
> the exact length is 13.  Error: 3.95%.


> Approximations for cos(phi) and sin(phi):

> Let phi be given in degrees (i.e, a right angle = 90).  (Note: phi is HALF
> the angle between the two whiskers.  So for an equilateral triangle, which
> has angles of 30 degrees, we have phi = 15.)

> Compute:  cos(phi) = 1                     if phi <= 7.5
>           cos(phi) = 1.0337 - 0.00452*phi  if phi >  7.5;

>           sin(phi) = 0.0059 + 0.01686*phi.

> Example: phi = 10 gives for the cosine the value 0.9885, and for the sine
> the value 0.1745.  The exact values are 0.9848 and 0.1736.

> The approximations are reasonable for phi between 0 and 45 degrees, and
> best for phi between 7 and 23 degrees.

> If phi is fixed, you can of course look them up once.

> --Lambert Meertens, CWI, Amsterdam; ·······@cwi.nl


And here is how I've done it in LeLisp.  dx and dy subsequently take
on the above A and B, L/R, xx and yy, sin(phi)*xx and sin(phi)*yy:

	    ; draw an arrowhead
	    (setq dx (abs (- x1 x2))
		  dy (abs (- y1 y2)))
	    (psetq dx (min dx dy)
		   dy (max dx dy))
	    (setq dx (/ 10 (+ (* .3978 dx) (* .9604 dy))))
	    (psetq dx (* (- x1 x2) dx)
		   dy (* (- y1 y2) dx))
	    ; (cos .3) and (sin .3)
	    (setq cx (* .9553 dx)
		  cy (* .9553 dy)
		  dx (* .2955 dx)
		  dy (* .2955 dy))
	    (draw-polyline 3
	       (vector (+ x2 (round (+ cx dy) 1))
		       x2
		       (+ x2 (round (- cx dy) 1)))
	       (vector (+ y2 (round (- cy dx) 1))
		       y2
		       (+ y2 (round (+ dx cy) 1))))

Someone also offered to send me an algo in Fortran, and someone else
later also sent me something similar looking in C, but since I didn't
yet have a request to summarize, I'm afraid I didn't keep any pointers.


 +---------------+
 |     * * *     |
 |   *       *   |	Beware - polyglot esperantist
 |  *         *  |
 |   *       *   |
 |     * * *     |
 +---------------+
 |
 |  Daniel Pfeiffer				<········@cix.cict.fr>
 |  Tolosa (Toulouse), Midi-Pyrenees, Europe	<········@irit.fr>
 |						<········@frcict81.bitnet>
 |