[pstricks] Automate a line drawing routine

Michael Sharpe msharpe at ucsd.edu
Wed Dec 31 01:32:14 CET 2008


On Dec 30, 2008, at 3:09 PM, Herbert Voss wrote:

> Michael Sharpe schrieb:
>
>> I think there's a problem here that goes back to the code for
>> \psIntersectionPoint, which gives a Postscript division by 0  error
>> where the lines are parallel. This makes your macro fail when the  
>> line
>> is either horizontal or vertical. (Try \psSlope(-4,2)(4,2).)
>
> Michael,
> this is not the problem with my example \psSlope(2,2)(4,1)
> it is the negative slope, which needs the nodes sorted in another
> order.
>
> Herbert
>
>
>> I think there needs to be a test in the code for the case where the
>> absolute value of the determinant of dX1 dY1//dX2 dY2 is small-- 
>> say, <.
>> 01 times the area of ABCD, and in this case, the intersection could  
>> be
>> declared to be 100 times the larger of (dX1,dY1), (dX2,dY2) plus the
>> basepoint. The current code tests only for dX1 or dX2 small, which is
>> not sufficient to prevent PostScript errors.
>

Herbert,

The problem happens only when you have too lines that are parallel and  
horizontal.

Try this: I get a PostScript error due to division by 0:

\pnode(1,1){P1}\pnode(3,1){P2}\pnode(1,2){P3}\pnode(4,2){P4}
\psIntersectionPoint(P1)(P2)(P3)(P4){Q}

Now try this modification of your \psIntersectionPoint code, which  
implements what I wrote earlier:

\makeatletter
\def\mypsIntersectionPoint(#1)(#2)(#3)(#4)#5{%
     \pst at getcoor{#1}\pst at tempA
     \pst at getcoor{#2}\pst at tempB
     \pst at getcoor{#3}\pst at tempC
     \pst at getcoor{#4}\pst at tempd
\pnode(!%
      \pst at tempA /YA exch \pst at number\psyunit div def
      /XA exch \pst at number\psxunit div def
      \pst at tempB /YB exch \pst at number\psyunit div def
      /XB exch \pst at number\psxunit div def
      \pst at tempC /YC exch \pst at number\psyunit div def
      /XC exch \pst at number\psxunit div def
      \pst at tempd /YD exch \pst at number\psyunit div def
      /XD exch \pst at number\psxunit div def
     /dY1 YB YA sub def
     /dX1 XB XA sub def
     /dY2 YD YC sub def
     /dX2 XD XC sub def
     /XAC XC XA sub def
     /YAC YC YA sub def
     /det dX1 dY2 mul dX2 dY1 mul sub def % determinant
     /Leng1 dX1 dY1 Pyth def
     /Leng2 dX2 dY2 Pyth def
     Leng1 Leng2 mul .01 mul det abs gt %angle between lines <.01  
radians
     {Leng1 Leng2 lt {100 dY2 mul 100 dX2 mul XC add exch YC add}
     {100 dY1 mul 100 dX1 mul XA add exch YA add} ifelse}
     %else angle between not small
     {XAC dY2 mul YAC dX2 mul sub det div dup dX1 mul XA add exch dY1  
mul YA add }
       ifelse
     ){#5}%
}
\makeatother

\pnode(1,1){P1}\pnode(3,1){P2}\pnode(1,2){P3}\pnode(4,2){P4}
\psIntersectionPoint(P1)(P2)(P3)(P4){Q}

This time, I get no error message---the intersection of these parallel  
line has been declared to be far away on the longer line segment,  
safely out of the picture. Perhaps the 100 should be 1000, and .01  
radians should be .001 radians.)

Michael


More information about the PSTricks mailing list