home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / gems / gemsiii / con2d.c < prev    next >
C/C++ Source or Header  |  1992-03-16  |  9KB  |  410 lines

  1. #include    <stdio.h>
  2.  
  3.  
  4. #define        OFFS                 4        /*    first & last segment min size    */
  5. #define        SMAX                20        /*    object min half size            */
  6.  
  7. #define        DIRECT                0
  8. #define        INVERSE                1
  9.  
  10. #define        LEFT                0x00
  11. #define        RIGHT                0x01
  12. #define        BOTTOM                0x02
  13. #define        TOP                    0x03
  14.  
  15. #define        EQSIGN(x1, x2, x3, x4)        ( ( x2 - x1 ) * ( x3 - x4 ) > 0 )
  16.  
  17. #define        CODE(x, y, w, h, px, py, c)    {                \
  18.                 c = 0x00;                                \
  19.                 if ( px < x ) c = 0x01;                    \
  20.                 else if ( px >= x + w ) c = 0x02;        \
  21.                 if ( py < y ) c |= 0x04;                \
  22.                 else if ( py >= y + h ) c |= 0x08;        \
  23.             }
  24.  
  25.  
  26. typedef    struct    {
  27.     int    direction;
  28.     int    x, y;
  29. }    Pad;
  30.  
  31. typedef    struct    {
  32.     int    x, y, w, h;
  33. }    Obj;
  34.  
  35.  
  36. /*****************************************************************************
  37. Computes & corrects the connection path from an object Out pad to an object In
  38. pad.
  39.  
  40. Entry:
  41.     startObj - the object to start the connection from
  42.     endObj   - the object to which the connection ends
  43.     outPad   - the Out pad to be connected
  44.     inPad    - the In pad to be connected
  45. Exit:
  46.     nump - the number of connection points
  47.     pts  - the connection point list
  48. *****************************************************************************/
  49.  
  50. ComputeCon ( startObj, endObj, outPad, inPad, nump, pts )
  51.     Obj    *startObj;
  52.     Obj    *endObj;
  53.     Pad    *outPad;
  54.     Pad *inPad;
  55.     int    nump;
  56.     int    pts[][2];
  57. {
  58.     nump = Connect(outPad->x, outPad->y, outPad->direction, 
  59.                    inPad->x, inPad->y, inPad->direction, pts);
  60.     Correct(startObj->x, startObj->y, startObj->w, startObj->h, nump, pts);
  61.     Correct(endObj->x, endObj->y, endObj->w, endObj->h, nump, pts);
  62. }
  63.  
  64.  
  65. /*****************************************************************************
  66. Computes the connection path from an object Out pad to an object In pad using 
  67. the orthogonal path algorithm.
  68.  
  69. Entry:
  70.     xo   - Out pad x coordinate
  71.     yo   - Out pad y coordinate
  72.     diro - Out pad direction
  73.     xi   - In pad x coordinate
  74.     yi   - In pad y coordinate
  75.     diri - In pad direction
  76. Exit:
  77.     p - the connection point list
  78. Return:
  79.     the number of connection points
  80. *****************************************************************************/
  81.  
  82. int    Connect ( xo, yo, diro, xi, yi, diri, p )
  83.     int    xo, yo, diro;
  84.     int    xi, yi, diri;
  85.     int    p[][2];
  86. {
  87.     static    int    directs[4][4] = {
  88.                     { TOP,    BOTTOM, LEFT,   RIGHT  }, 
  89.                     { BOTTOM, TOP,    RIGHT,  LEFT   }, 
  90.                     { RIGHT,  LEFT,   TOP,    BOTTOM }, 
  91.                     { LEFT,   RIGHT,  BOTTOM, TOP    }
  92.                 };
  93.     int    i, np, txi, tyi;
  94.  
  95.     Transform(DIRECT, diro, xo, yo, xi, yi, &txi, &tyi);
  96.     switch ( directs[diro][diri] ) {            /* In pad direction    */
  97.         case LEFT:
  98.             if ( tyi > 0 ) {                    /*    T    */
  99.                 if ( txi > 0 ) {                /*    34    */
  100.                     Shape3P(txi, tyi, p);
  101.                     np = 3;
  102.                 }
  103.                 else {                            /*    12    */
  104.                     Shape5PB(txi, tyi, -1, p);
  105.                     np = 5;
  106.                 }
  107.             }
  108.             else {                                /*    B    */
  109.                 Shape5PB(txi, tyi, -1, p);
  110.                 np = 5;
  111.             }
  112.             break;
  113.         case RIGHT:
  114.             if ( tyi > 0 ) {                    /*    T    */
  115.                 if ( txi > 0 ) {                /*    34    */
  116.                     Shape5PB(txi, tyi, 1, p);
  117.                     np = 5;
  118.                 }
  119.                 else {                            /*    12    */
  120.                     Shape3P(txi, tyi, p);
  121.                     np = 3;
  122.                 }
  123.             }
  124.             else {                                /*    B    */
  125.                 Shape5PB(txi, tyi, 1, p);
  126.                 np = 5;
  127.             }
  128.             break;
  129.         case BOTTOM:
  130.             if ( tyi > 0 ) {                    /*    T    */
  131.                 Shape4PD(txi, tyi, p);
  132.                 np = 4;
  133.             }
  134.             else {                                /*    B    */
  135.                 Shape6P(txi, tyi, -1, p);
  136.                 np = 6;
  137.             }
  138.             break;
  139.         case TOP:
  140.             if ( txi < - SMAX || txi > SMAX ) {    /*    14    */
  141.                 Shape4PU(txi, tyi, p);
  142.                 np = 4;
  143.             }
  144.             else {                                /*    23    */
  145.                 Shape6R(txi, tyi, 1, p);
  146.                 np = 6;
  147.             }
  148.             break;
  149.     }
  150.     for ( i = 0 ; i < np ; i++ ) 
  151.         Transform(INVERSE, diro, xo, yo, p[i][0], p[i][1], &p[i][0], &p[i][1]);
  152.     return (np);
  153. }
  154.  
  155.  
  156. /*****************************************************************************
  157. Translates & rotates a point according to the Out pad direction.
  158.  
  159. Entry:
  160.     mode - transformation mode (DIRECT or INVERSE)
  161.     dout - Out pad direction
  162.     xout - Out pad x coordinate
  163.     yout - Out pad y coordinate
  164.     x, y - point to be transformed
  165. Exit:
  166.     tx, ty - transformed point
  167. *****************************************************************************/
  168.  
  169. Transform ( mode, dout, xout, yout, x, y, tx, ty )
  170.     int    mode;
  171.     int    dout, xout, yout;
  172.     int    x, y;
  173.     int    *tx, *ty;
  174. {
  175.     int    ox, oy;
  176.  
  177.     ox = x;
  178.     oy = y;
  179.     switch ( mode ) {
  180.         case DIRECT:
  181.             switch ( dout ) {
  182.                 case LEFT:
  183.                     *tx = oy - yout;
  184.                     *ty = xout - ox;
  185.                     break;
  186.                 case RIGHT:
  187.                     *tx = yout - oy;
  188.                     *ty = ox - xout;
  189.                     break;
  190.                 case BOTTOM:
  191.                     *tx = xout - ox;
  192.                     *ty = yout - oy;
  193.                     break;
  194.                 case TOP:
  195.                     *tx = ox - xout;
  196.                     *ty = oy - yout;
  197.                     break;
  198.             }
  199.             break;
  200.         case INVERSE:
  201.             switch ( dout ) {
  202.                 case LEFT:
  203.                     *tx = xout - oy;
  204.                     *ty = yout + ox;
  205.                     break;
  206.                 case RIGHT:
  207.                     *tx = xout + oy;
  208.                     *ty = yout - ox;
  209.                     break;
  210.                 case BOTTOM:
  211.                     *tx = xout - ox;
  212.                     *ty = yout - oy;
  213.                     break;
  214.                 case TOP:
  215.                     *tx = xout + ox;
  216.                     *ty = yout + oy;
  217.                     break;
  218.             }
  219.             break;
  220.     }
  221. }
  222.  
  223.  
  224. /*****************************************************************************
  225. Corrects the connection path moving the overcrossing segments out of the
  226. crossed object.
  227.  
  228. Entry:
  229.     x, y - object lower left corner
  230.     w, h - object width & height
  231.     np   - number of connection point
  232.     p    - original path points list
  233. Exit:
  234.     p - eventually corrected path points list
  235. *****************************************************************************/
  236.  
  237. Correct ( x, y, w, h, np, p )
  238.     int    x, y, w, h;
  239.     int    np;
  240.     int    p[][2];
  241. {
  242.     int    i, j, c, op[2], od[2];
  243.  
  244.     op[0] = x;
  245.     op[1] = y;
  246.     od[0] = w;
  247.     od[1] = h;
  248.     for ( j = 1, i = 2 ; i < np - 1 ; i++, j++ ) {
  249.         if ( Overcross(x, y, w, h, p[j][0], p[j][1], p[i][0], p[i][1]) ) {
  250.             c = ( p[j][0] == p[i][0] ) ? 0 : 1;
  251.             if ( EQSIGN(p[j-1][c], p[j][c], p[i][c], p[i+1][c]) ) {
  252.                 if ( p[j][c] < p[j-1][c] ) 
  253.                     p[j][c] = p[i][c] = op[c] - OFFS + 2;
  254.                 else p[j][c] = p[i][c] = op[c] + od[c] - 1 + OFFS - 2;
  255.             }
  256.             else {
  257.                 if ( p[i][c] < p[i+1][c] ) 
  258.                     p[j][c] = p[i][c] = op[c] - OFFS + 2;
  259.                 else p[j][c] = p[i][c] = op[c] + od[c] - 1 + OFFS - 2;
  260.             }
  261.         }
  262.     }
  263. }
  264.  
  265.  
  266. /*****************************************************************************
  267. Inplementation of line-rectangle intersection test as the first test in 
  268. Cohen-Sutherland clipping algorithm.
  269.  
  270. Entry:
  271.     x, y   - rectangle lower left corner
  272.     w, h   - rectangle width & height
  273.     x1, y1 - line start point
  274.     x2, y2 - line end point
  275. Return:
  276.     TRUE if the line overcrosses the rectangle, FALSE otherwise
  277. *****************************************************************************/
  278.  
  279. int    Overcross ( x, y, w, h, x1, y1, x2, y2 )
  280.     int    x, y, w, h;
  281.     int    x1, y1, x2, y2;
  282. {
  283.     int    c1, c2;
  284.  
  285.     CODE(x, y, w, h, x1, y1, c1);
  286.     CODE(x, y, w, h, x2, y2, c2);
  287.     return(! ( c1 & c2));
  288. }
  289.  
  290.  
  291. /*****************************************************************************
  292. Shape functions.
  293.  
  294. Entry:
  295.     xi, yi - In pad coordinate
  296.     [sign] - sign flag
  297. Exit:
  298.     xy - the computed path points list
  299. *****************************************************************************/
  300.  
  301. Shape3P ( xi, yi, xy )
  302.     int    xi, yi;
  303.     int    xy[][2];
  304. {
  305.     xy[0][0] = 0;
  306.     xy[0][1] = 0;
  307.     xy[1][0] = 0;
  308.     xy[1][1] = yi;
  309.     xy[2][0] = xi;
  310.     xy[2][1] = yi; 
  311. }
  312.  
  313.  
  314. Shape4PD ( xi, yi, xy )
  315.     int    xi, yi;
  316.     int    xy[][2];
  317. {
  318.     xy[0][0] = 0;
  319.     xy[0][1] = 0;
  320.     xy[1][0] = 0;
  321.     xy[1][1] = OFFS;
  322.     xy[2][0] = xi;
  323.     xy[2][1] = xy[1][1]; 
  324.     xy[3][0] = xi;
  325.     xy[3][1] = yi; 
  326. }
  327.  
  328.  
  329. Shape4PU ( xi, yi, xy )
  330.     int    xi, yi;
  331.     int    xy[][2];
  332. {
  333.     xy[0][0] = 0;
  334.     xy[0][1] = 0;
  335.     xy[1][0] = 0;
  336.     xy[1][1] = ( ( yi <= 0 ) ? 0 : yi ) + OFFS;
  337.     xy[2][0] = xi;
  338.     xy[2][1] = xy[1][1]; 
  339.     xy[3][0] = xi;
  340.     xy[3][1] = yi; 
  341. }
  342.  
  343.  
  344. Shape5PB ( xi, yi, sign, xy )
  345.     int    xi, yi;
  346.     int    sign;
  347.     int    xy[][2];
  348. {
  349.     xy[0][0] = 0;
  350.     xy[0][1] = 0;
  351.     xy[1][0] = 0;
  352.     xy[1][1] = OFFS;
  353.     if ( sign * xi < - SMAX ) xy[2][0] = xi + sign * OFFS;
  354.     else xy[2][0] = ( ( sign * xi < 0 ) ? 0 : xi ) + sign * OFFS;
  355.     xy[2][1] = xy[1][1]; 
  356.     xy[3][0] = xy[2][0];
  357.     xy[3][1] = yi; 
  358.     xy[4][0] = xi;
  359.     xy[4][1] = yi; 
  360. }
  361.  
  362.  
  363. Shape5PT ( xi, yi, sign, xy )
  364.     int    xi, yi;
  365.     int    sign;
  366.     int    xy[][2];
  367. {
  368.     xy[0][0] = 0;
  369.     xy[0][1] = 0;
  370.     xy[1][0] = 0;
  371.     xy[1][1] = OFFS;
  372.     xy[2][0] = xi + sign * OFFS;
  373.     xy[2][1] = xy[1][1]; 
  374.     xy[3][0] = xy[2][0];
  375.     xy[3][1] = yi; 
  376.     xy[4][0] = xi;
  377.     xy[4][1] = yi; 
  378. }
  379.  
  380.  
  381. Shape6P ( xi, yi, sign, xy )
  382.     int    xi, yi;
  383.     int    sign;
  384.     int    xy[][2];
  385. {
  386.     int    xm;
  387.  
  388.     xm       = xi / 2;
  389.     xy[0][0] = 0;
  390.     xy[0][1] = 0;
  391.     xy[1][0] = 0;
  392.     xy[1][1] = OFFS;
  393.     if ( yi < 0 ) {
  394.         if ( xi > 0 ) xy[2][0] = ( xm > SMAX ) ? xm : SMAX;
  395.         else xy[2][0] = ( xm > SMAX ) ? xm : - SMAX;
  396.     }
  397.     else {
  398.         if ( xi > 0 ) xy[2][0] = ( xm > SMAX ) ? xm : - SMAX;
  399.         else xy[2][0] = ( xm > SMAX ) ? xm : SMAX;
  400.     }
  401.     xy[2][1] = xy[1][1]; 
  402.     xy[3][0] = xy[2][0];
  403.     xy[3][1] = yi + sign * OFFS;
  404.     xy[4][0] = xi;
  405.     xy[4][1] = xy[3][1]; 
  406.     xy[5][0] = xi;
  407.     xy[5][1] = yi; 
  408. }
  409.  
  410.