home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_02_03 / 2n03050a < prev    next >
Text File  |  1991-01-15  |  11KB  |  401 lines

  1.  
  2. /********************************************************************
  3. * BEZDIS.C -- Interactive Bezier Curve Display.
  4. *
  5. * Author : Bob Zigon
  6. * Date   : July 26, 1989
  7. ********************************************************************/
  8. #include "stdio.h"
  9. #include "stdlib.h"
  10. #include "string.h"
  11. #include "bios.h"
  12. #include "graphics.h"
  13.  
  14. #include "keys.h"
  15.  
  16. /*******************************************************************
  17. *                       Global Defines
  18. ********************************************************************/
  19. #define OFF           0
  20. #define ON           (!OFF)
  21.  
  22. #define MAXTDivisions 150
  23. #define MINTDivisions 30
  24. #define MAXCP         10
  25. #define CPDx          0.05
  26. #define CPDy          0.05
  27.  
  28. /*******************************************************************
  29. *                      Variable Declarations
  30. ********************************************************************/
  31. double XCp[MAXCP+1],        /* X Control Points */
  32.        YCp[MAXCP+1];        /* Y Control Points */
  33.  
  34. short int XCpScr[MAXCP+1],
  35.           YCpScr[MAXCP+1];
  36.  
  37. double XCurve[MAXTDivisions+1],   /* X Curve Points */
  38.        YCurve[MAXTDivisions+1];   /* Y Curve Points */
  39.  
  40. short int Xv[MAXTDivisions+1],
  41.           Yv[MAXTDivisions+1];
  42.  
  43. short int XvpMin,                 /* Viewport dimensions */
  44.           XvpMax,
  45.           YvpMin,
  46.           YvpMax,
  47.           XsMax,                  /* Screen Dimensions in pixels */
  48.           YsMax;
  49.  
  50. short int TDivisions = MINTDivisions,
  51.           NumCP,
  52.           CurCP = 0,
  53.           Refresh = ON;
  54.  
  55. short int CurveColor,
  56.           LineColor,
  57.           CrossColor,
  58.           BgdColor;
  59.  
  60. double XCpMin = 0.0,
  61.        XCpMax = 5.0,
  62.        YCpMin = 0.0,
  63.        YCpMax = 5.0;
  64.  
  65. char *HelpMsg[] =
  66. {
  67.    " F1    - Help",
  68.    " F2    - Toggle refresh of CP line segments",
  69.    " ",
  70.    " Left  - Move current CP left 1 unit",
  71.    " Right - Move current CP right 1 unit",
  72.    " Up    - Move current CP up 1 unit",
  73.    " Down  - Move current CP down 1 unit",
  74.    " ",
  75.    " PgUp  - Next CP",
  76.    " PgDn  - Prev CP",
  77.    " Ins   - Insert CP",
  78.    " Del   - Delete CP",
  79.    " ",
  80.    " Home  - Add 5 to number of parametric divisions",
  81.    " End   - Sub 5 from number of parametric divisions ",
  82.    " ",
  83.    " ESC   - QUIT"
  84. };
  85.  
  86. #define NUMHELP  (sizeof(HelpMsg)/sizeof(char *))
  87.  
  88. /*******************************************************************
  89. *                       Function Prototypes
  90. ********************************************************************/
  91. void Binomial(short int NumControl), UpdateStatus(void);
  92. void BezierToScreen(short int, short int, short int *, short int *);
  93. short int GetInput(void), Check8087(void);
  94. void Initialize(void), DrawCurve(short int), DrawCross(short int);
  95. void WToVConst(void), GetHelp(void);
  96.  
  97. void main()
  98. {
  99.    short int i, cc;
  100.  
  101.    Initialize();
  102.  
  103.    WToVConst();
  104.    Binomial(NumCP);
  105.    BezierToScreen(TDivisions, NumCP, Xv, Yv);
  106.    DrawCurve(ON);
  107.    UpdateStatus();
  108.  
  109.    while ((cc = GetInput()) != ESC)
  110.       switch (cc)
  111.       {
  112.          case F1    : GetHelp();
  113.                       break;
  114.  
  115.          case F2    : DrawCurve(OFF);
  116.                       Refresh = !Refresh;
  117.                       DrawCurve(ON);
  118.                       UpdateStatus();
  119.                       break;
  120.  
  121.          case LEFT  : if (XCp[CurCP]-CPDx > XCpMin)
  122.                       {
  123.                          DrawCurve(OFF);
  124.                          XCp[CurCP] -= CPDx;
  125.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  126.                          DrawCurve(ON);
  127.                       }
  128.                       break;
  129.  
  130.          case RIGHT : if (XCp[CurCP]+CPDx < XCpMax)
  131.                       {
  132.                          DrawCurve(OFF);
  133.                          XCp[CurCP] += CPDx;
  134.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  135.                          DrawCurve(ON);
  136.                       }
  137.                       break;
  138.  
  139.          case DOWN  : if (YCp[CurCP]-CPDy > YCpMin)
  140.                       {
  141.                          DrawCurve(OFF);
  142.                          YCp[CurCP] -= CPDy;
  143.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  144.                          DrawCurve(ON);
  145.                       }
  146.                       break;
  147.  
  148.          case UP    : if (YCp[CurCP]+CPDy < YCpMax)
  149.                       {
  150.                          DrawCurve(OFF);
  151.                          YCp[CurCP] += CPDy;
  152.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  153.                          DrawCurve(ON);
  154.                       }
  155.                       break;
  156.  
  157.          case PGUP  : if (CurCP+1 < NumCP)
  158.                       {
  159.                          DrawCross(BgdColor);
  160.                          CurCP++;
  161.                          DrawCurve(ON);
  162.                          DrawCross(CrossColor);
  163.                          UpdateStatus();
  164.                       }
  165.                       break;
  166.  
  167.          case PGDN  : if (CurCP-1 > -1)
  168.                       {
  169.                          DrawCross(BgdColor);
  170.                          CurCP--;
  171.                          DrawCurve(ON);
  172.                          DrawCross(CrossColor);
  173.                          UpdateStatus();
  174.                       }
  175.                       break;
  176.  
  177.          case HOME  : if (TDivisions+5 < MAXTDivisions)
  178.                       {
  179.                          DrawCurve(OFF);
  180.                          TDivisions += 5;
  181.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  182.                          DrawCurve(ON);
  183.                          UpdateStatus();
  184.                       }
  185.                       break;
  186.  
  187.          case END   : if (TDivisions-5 >= MINTDivisions)
  188.                       {
  189.                          DrawCurve(OFF);
  190.                          TDivisions -= 5;
  191.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  192.                          DrawCurve(ON);
  193.                          UpdateStatus();
  194.                       }
  195.                       break;
  196.  
  197.          case INS   : if (NumCP+1 < MAXCP && CurCP+1 != NumCP)
  198.                       {
  199.                          DrawCurve(OFF);
  200.                          for (i = NumCP++; i > CurCP; i--)
  201.                          {
  202.                             XCp[i] = XCp[i-1];
  203.                             YCp[i] = YCp[i-1];
  204.                          }
  205.  
  206.                          Binomial(NumCP);
  207.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  208.                          DrawCurve(ON);
  209.                          UpdateStatus();
  210.                       }
  211.                       break;
  212.  
  213.          case DEL   : if (NumCP > 2)
  214.                       {
  215.                          DrawCurve(OFF);
  216.                          for (i = CurCP, NumCP--; i < NumCP; i++)
  217.                          {
  218.                             XCp[i] = XCp[i+1];
  219.                             YCp[i] = YCp[i+1];
  220.                          }
  221.                          if (CurCP == NumCP)
  222.                             CurCP--;
  223.                          Binomial(NumCP);
  224.                          BezierToScreen(TDivisions, NumCP, Xv, Yv);
  225.                          DrawCurve(ON);
  226.                          UpdateStatus();
  227.                       }
  228.                       break;
  229.       }
  230.  
  231.    closegraph();
  232. }
  233.  
  234. void Initialize()
  235. {
  236.    int Gdriver, Gmode;
  237.  
  238.    if (Check8087() == 0)
  239.    {
  240.       printf("\nNo Arithmetic Coprocessor Present.");
  241.       exit(1);
  242.    }
  243.  
  244.    detectgraph(&Gdriver, &Gmode);
  245.  
  246.    if (Gdriver < 0)
  247.    {
  248.       printf("\nError : No graphics hardware detected.");
  249.       exit(1);
  250.    }
  251.  
  252.    if (Gmode == CGAHI)
  253.       Gmode = CGAC0;
  254.  
  255.    initgraph(&Gdriver, &Gmode, "");
  256.  
  257.    XvpMin = 5;
  258.    YvpMin = 5;
  259.    XvpMax = getmaxx()-5;
  260.    YvpMax = getmaxy()-3-textheight("A");
  261.    XsMax  = getmaxx();
  262.    YsMax  = getmaxy();
  263.  
  264.    if (Gdriver == CGA)
  265.    {
  266.       BgdColor   = 0;
  267.       CurveColor = CGA_GREEN;
  268.       LineColor  = CGA_BROWN;
  269.       CrossColor = CGA_RED;
  270.    }
  271.    else
  272.    {
  273.       BgdColor   = BLACK;
  274.       CurveColor = WHITE;
  275.       LineColor  = YELLOW;
  276.       CrossColor = RED;
  277.    }
  278.  
  279.    NumCP  = 4;
  280.    XCp[0] = 1.0; YCp[0] = 1.0;
  281.    XCp[1] = 2.0; YCp[1] = 3.0;
  282.    XCp[2] = 4.0; YCp[2] = 3.0;
  283.    XCp[3] = 3.0; YCp[3] = 1.0;
  284. }
  285.  
  286. void DrawCurve(OnOff)
  287. short int OnOff;
  288. {
  289.    register short int i;
  290.  
  291.       if (OnOff == OFF)
  292.       {
  293.          DrawCross(BgdColor);
  294.  
  295.          if (Refresh == ON)
  296.          {
  297.             moveto(XCpScr[0], YCpScr[0]);
  298.             for (i = 1; i < NumCP; i++)
  299.                lineto(XCpScr[i], YCpScr[i]);
  300.          }
  301.  
  302.          moveto(Xv[0], Yv[0]);
  303.          for (i = 1; i < TDivisions+1; i++)
  304.             lineto(Xv[i], Yv[i]);
  305.       }
  306.       else
  307.       {
  308.          setcolor(LineColor);
  309.          if (Refresh == ON)
  310.          {
  311.             moveto(XCpScr[0], YCpScr[0]);
  312.             for (i = 1; i < NumCP; i++)
  313.                lineto(XCpScr[i], YCpScr[i]);
  314.          }
  315.  
  316.          setcolor(CurveColor);
  317.          moveto(Xv[0], Yv[0]);
  318.          for (i = 1; i < TDivisions+1; i++)
  319.             lineto(Xv[i], Yv[i]);
  320.  
  321.          DrawCross(CrossColor);
  322.       }
  323. }
  324.  
  325. void DrawCross(color)
  326. short int color;
  327. {
  328.    setcolor(color);
  329.    line(XCpScr[CurCP]-3, YCpScr[CurCP], XCpScr[CurCP]+3, YCpScr[CurCP]);
  330.    line(XCpScr[CurCP], YCpScr[CurCP]-3, XCpScr[CurCP], YCpScr[CurCP]+3);
  331. }
  332.  
  333. void UpdateStatus()
  334. {
  335.    char buf[80];
  336.  
  337.    setviewport(0, YvpMax+1, XsMax,  YsMax, 0);
  338.    clearviewport();
  339.    setcolor(LineColor);
  340.    sprintf(buf, "  CP %2d of %2d  Div: %3d ", CurCP+1, NumCP, TDivisions);
  341.    outtextxy(0, 0, buf);
  342.    setviewport(0, 0, XsMax, YsMax, 0);
  343. }
  344.  
  345. void GetHelp()
  346. {
  347.    short int HelpL, HelpR, HelpT, HelpB;
  348.    short int i, THgt, MaxLen, HSize, MaxHgt;
  349.    char *Buf;
  350.  
  351.    for (i = 0, MaxLen = 0; i < NUMHELP; i++)
  352.      if (strlen(HelpMsg[i]) > MaxLen)
  353.         MaxLen = strlen(HelpMsg[i]);
  354.  
  355.    MaxLen *= textwidth("A");
  356.    THgt   = textheight("A");
  357.    MaxHgt = THgt*NUMHELP;
  358.  
  359.    HelpL = (XsMax-MaxLen)/2;
  360.    HelpR = HelpL+MaxLen+5;
  361.    HelpT = (YsMax-MaxHgt)/2;
  362.    HelpB = HelpT+MaxHgt+5;
  363.  
  364.    HSize = imagesize(HelpL, HelpT, HelpR, HelpB);
  365.    if ((Buf=malloc(HSize)) == NULL)
  366.       return;
  367.  
  368.    getimage(HelpL, HelpT, HelpR, HelpB, Buf);
  369.    setviewport(HelpL, HelpT, HelpR, HelpB, 1);
  370.    clearviewport();
  371.    setcolor(LineColor);
  372.  
  373.    line(0, 0, MaxLen+4, 0);
  374.    line(MaxLen+4, 0, MaxLen+4, MaxHgt+4);
  375.    line(MaxLen+4, MaxHgt+4, 0, MaxHgt+4);
  376.    line(0, MaxHgt+4, 0, 0);
  377.  
  378.    for (i = 0; i < NUMHELP; i++)
  379.       outtextxy(2, i*THgt+2, HelpMsg[i]);
  380.  
  381.    while (GetInput() != ESC)
  382.       ;
  383.  
  384.    setviewport(0, 0, XsMax, YsMax, 0);
  385.    putimage(HelpL, HelpT, Buf, COPY_PUT);
  386.    free(Buf);
  387. }
  388.  
  389. short int GetInput(void)
  390. {
  391.    short int key;
  392.  
  393.    /*
  394.     * If it is not an extended key, then return the ascii value.
  395.    */
  396.    if ((key = bioskey(0)) & 0xFF)
  397.       return (key & 0xFF);
  398.  
  399.    return (0x200 + ((key & 0xFF00) >> 8));
  400. }
  401.