home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 136.lha / AirFoil / airfoilx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-20  |  13.2 KB  |  503 lines

  1. /********************************************************************
  2. *                                                                   *
  3. * Joukowski Airfoil Generator with Streamline and Pressure          *
  4. * Distribution Algorithms                                           *
  5. *                                                                   *
  6. * Written by:   Russell Leighton      15 March 1987                 *
  7. *               Lancaster, CA                                       *
  8. *                                                                   *
  9. * Expansion memory fixes by Fred Wright, 1 Jun 1987                 *
  10. *                                                                   *
  11. ********************************************************************/
  12.  
  13. #include "airfoilx.h"
  14.  
  15. main()
  16. {
  17.    float rs,theta,h,vel;
  18.    int psi;
  19.    ULONG MessageClass;
  20.  
  21.    open_things();
  22.    do_about();
  23.  
  24.    /****************/
  25.    /* Loop forever */
  26.    /****************/
  27.  
  28.    for(;;)
  29.    {
  30.       while (Continue)
  31.       {
  32.          /****************************************************/
  33.          /* Wait, initially and after each plot, for user to */
  34.          /* bring up the double menu requester               */
  35.          /****************************************************/
  36.  
  37.          Wait(1L<<w->UserPort->mp_SigBit);
  38.          if((message = (struct IntuiMessage *)GetMsg(w->UserPort)) != NULL)
  39.          {
  40.             MessageClass = message->Class;
  41.             ReplyMsg(message);
  42.             if (MessageClass == REQVERIFY)
  43.             {
  44.                do_request();
  45.                break;
  46.             }
  47.          } /* end if */
  48.       } /* end while */
  49.  
  50.       do_init();
  51.  
  52.       if(mode)
  53.       {
  54.  
  55.          /********************/
  56.          /* Plot Streamlines */
  57.          /********************/
  58.  
  59.          FILL = TRUE;
  60.          for (psi = 12;psi > 0;--psi)
  61.          {
  62.             do_mess();
  63.             if(!Continue) break;
  64.  
  65.             PENUP;
  66.             SetAPen(rp,(long)(psi+1));
  67.             SetBPen(rp,(long)(psi+1));
  68.  
  69.             for (theta = 0.015;theta < TWO_PI;theta += PI/100)
  70.             {
  71.                vel = 2*velocity*sin(theta);
  72.                vel = abs(vel);
  73.                rs = (psi+sqrt(psi*psi+r*r*vel*vel))/vel;
  74.                transform(rs,theta);
  75.             } /* end for */
  76.             AreaEnd(rp);
  77.          } /* end for */
  78.  
  79.          /*******************************/
  80.          /* Plot Stagnation Streamlines */
  81.          /*******************************/
  82.  
  83.          do_mess();
  84.          if(Continue)
  85.          {
  86.             FILL = FALSE;
  87.             PENUP;
  88.             SetAPen(rp,1L);
  89.             h = (r-4.0)/40.0;
  90.             theta = 0.0;
  91.  
  92.             for (rs = 4;rs >= r;rs += h)
  93.             {
  94.                transform(rs,theta);
  95.             }
  96.  
  97.             PENUP;
  98.             theta = PI;
  99.  
  100.             for (rs = 4;rs > r;rs += h)
  101.             {
  102.                transform(rs,theta);
  103.             }
  104.          } /* end if */
  105.       } /* end if */
  106.  
  107.       else
  108.       {
  109.  
  110.          /******************************/
  111.          /* Plot Pressure Distribution */
  112.          /******************************/
  113.  
  114.          do_mess();
  115.          if(Continue)
  116.          {
  117.             FILL = TRUE;
  118.             PENUP;
  119.             SetAPen(rp,2L);
  120.             SetBPen(rp,2L);
  121.  
  122.             for (theta = 0.0;theta <= TWO_PI;theta += PI/100)
  123.             {
  124.                rs = r+sin(theta)*sin(theta);
  125.                transform(rs,theta);
  126.             } /* end for */
  127.             AreaEnd(rp);
  128.          } /* end if */
  129.       } /* end else */
  130.  
  131.       /****************/
  132.       /* Plot Airfoil */
  133.       /****************/
  134.  
  135.       do_mess();
  136.       if(Continue)
  137.       {
  138.          FILL = TRUE;
  139.          PENUP;
  140.          rs = r;
  141.          SetAPen(rp,1L);
  142.          SetBPen(rp,1L);
  143.  
  144.          for (theta = 0.0;theta <= TWO_PI;theta += PI/100)
  145.          {
  146.             transform(rs,theta);
  147.          }
  148.          AreaEnd(rp);
  149.       } /* end if */
  150.    } /* end forever */
  151. } /* end main */
  152.  
  153. do_init()
  154. {
  155.    float a0;
  156.  
  157.    SetAPen(rp,0L);
  158.    RectFill(rp,(long)(XMIN+1),(long)(YMIN+1),(long)(XMAX-1),(long)(YMAX-1));
  159.    SetOPen(rp,1L);
  160.  
  161.    /***********************************************************/
  162.    /* Calculate circle constants (circle center and radius)   */
  163.    /* from airfoil constants through a reverse transformation */
  164.    /***********************************************************/
  165.  
  166.    alpha = (float)angle*PI/180;
  167.    c = (float)camber/25;
  168.    t = (float)thickness/25;
  169.    a = 0;
  170.    b = c/2;
  171.  
  172.    do
  173.    {
  174.       a0 = a;
  175.       a = t*(2*a0+1)/4/sqrt(b*b+2*a0+1);
  176.       b = c*(1+2*a)/(2+2*a);
  177.    }
  178.    while(abs(a-a0) > TOL);
  179.    
  180.    r = sqrt(b*b+(a+1)*(a+1));
  181.    Continue = TRUE;
  182. }
  183.  
  184. do_mess()
  185. {
  186.    ULONG MessageClass;
  187.  
  188.    /******************************************************************/
  189.    /* Check for double menu requester. This can be brought up at any */
  190.    /* time but can not be displayed unless the message is replied    */
  191.    /* to, therefore this routine must be called periodically.        */
  192.    /******************************************************************/
  193.  
  194.    if((message = (struct IntuiMessage *)GetMsg(w->UserPort)) != NULL)
  195.    {
  196.       MessageClass = message->Class;
  197.       ReplyMsg(message);
  198.       if(MessageClass == REQVERIFY) do_request();
  199.    }
  200.    ixo = XCEN;
  201.    iyo = YCEN;
  202. }
  203.  
  204. transform(rs,theta)
  205.  
  206. float rs,theta;
  207. {
  208.    float x,y,z,u,v;
  209.    int PLOT;
  210.    long ix,iy,cx,cy;
  211.  
  212.    /********************************************************************/
  213.    /* This is the Joukowski transformation routine. This is also where */
  214.    /* the plotting is done. Plotting is usually done using the area    */
  215.    /* fill routines (AreaDraw & AreaMove). If FILL is true then the    */
  216.    /* points are used to build up the area shape to be filled. See the */
  217.    /* Rom Kernal manual containing the graphics primatives for more    */
  218.    /* details. If FILL is false then normal plotting is done.          */
  219.    /********************************************************************/
  220.  
  221.    x = rs*cos(theta-alpha)+a;
  222.    y = rs*sin(theta-alpha)+b;
  223.    z = 1/(x*x+y*y);
  224.    u = x*(1+z)*cos(alpha)-y*(1-z)*sin(alpha);
  225.    v = y*(1-z)*cos(alpha)+x*(1+z)*sin(alpha);
  226.  
  227.    ix = (long)(SFAC*u+XCEN);
  228.    iy = (long)(YCEN-SFAC*v);
  229.  
  230.    if(FILL)
  231.    {
  232.       PLOT = FALSE;
  233.       cx = ix;
  234.       cy = iy;
  235.  
  236.       /*************************************************************/
  237.       /* This subroutine also clips the display area, hence the    */
  238.       /* following statements. Contrary to the what the Rom Kernal */
  239.       /* manual states, all clipping must be done by the program   */
  240.       /* if the area fill routines are used otherwise a nasty      */
  241.       /* crash will result if plotting takes place out of bounds.  */
  242.       /* Only the x values are clipped accurately since, for this  */
  243.       /* routine only the x values at the boundary need to be      */
  244.       /* accurate. The PEN parameter indicates the pen status for  */
  245.       /* moves and draws as set by either PENUP or PENDOWN.        */
  246.       /*************************************************************/
  247.  
  248.       if((ix <= XMIN) && (ixo > XMIN))
  249.       {
  250.          cy += (float)(iyo-iy)*(XMIN-ix)/(ixo-ix);
  251.          cx = XMIN;
  252.       }
  253.       else if((ixo <= XMIN) && (ix > XMIN))
  254.       {
  255.          iyo += (float)(iy-iyo)*(XMIN-ixo)/(ix-ixo);
  256.          ixo = XMIN;
  257.          AreaDraw(rp,ixo,iyo);
  258.          PLOT = TRUE;
  259.       }
  260.       else if((ix >= XMAX) && (ixo < XMAX))
  261.       {
  262.          cy += (float)(iyo-iy)*(XMAX-ix)/(ixo-ix);
  263.          cx = XMAX;
  264.       }
  265.       else if((ixo >= XMAX) && (ix < XMAX))
  266.       {
  267.          iyo += (float)(iy-iyo)*(XMAX-ixo)/(ix-ixo);
  268.          ixo = XMAX;
  269.          AreaDraw(rp,ixo,iyo);
  270.          PLOT = TRUE;
  271.       }
  272.  
  273.       if((ixo > XMIN) && (ixo < XMAX)) PLOT = TRUE;
  274.       if(cy < YMIN) cy = YMIN;
  275.       if(cy > YMAX) cy = YMAX;
  276.  
  277.       if(PLOT)
  278.       {
  279.          if(PEN) AreaDraw(rp,cx,cy);
  280.          else { AreaMove(rp,cx,cy); PENDOWN; }
  281.       }
  282.       ixo = ix;
  283.       iyo = iy;
  284.    }
  285.    else
  286.    {
  287.       if(PEN) Draw(rp,ix,iy);
  288.       else { Move(rp,ix,iy); PENDOWN; }
  289.    }
  290. }
  291.  
  292. do_request()
  293. {
  294.    ULONG MessageClass;
  295.  
  296.    /***************************************************************/
  297.    /* This subroutine is activated when the double menu requester */
  298.    /* is brought up. It handles all input from this requester.    */
  299.    /***************************************************************/
  300.  
  301.    if(title) ShowTitle(s,FALSE);
  302.  
  303.    for (;;)
  304.    {
  305.       Wait(1L<<w->UserPort->mp_SigBit);
  306.       if((message = (struct IntuiMessage *)GetMsg(w->UserPort)) != NULL)
  307.       {
  308.          MessageClass = message->Class;
  309.          ReplyMsg(message);
  310.          switch (MessageClass)
  311.          {
  312.             case GADGETUP    :
  313.  
  314.             case GADGETDOWN  : if (do_gadgets(message) == CLOSE_GAD)
  315.                                {
  316.                                   if(title) ShowTitle(s,TRUE);
  317.                                   return;
  318.                                }
  319.                                break;
  320.          } /* end switch */
  321.       } /* end if */
  322.    } /* end forever */
  323. }
  324.  
  325. int do_gadgets(mes)
  326.  
  327. struct IntuiMessage *mes;
  328. {
  329.    struct Gadget *igad;
  330.    int gadgid;
  331.  
  332.    /*********************************************/
  333.    /* This subroutine handles all gadget input. */
  334.    /*********************************************/
  335.  
  336.    igad = (struct Gadget *)mes->IAddress;
  337.    gadgid = igad->GadgetID;
  338.  
  339.    switch(gadgid)
  340.    {
  341.       case CAMBER_GAD   : camber = (ULONG)camber_string.LongInt;
  342.                           Continue = FALSE;
  343.                           break;
  344.  
  345.       case THICK_GAD    : thickness = (ULONG)thick_string.LongInt;
  346.                           Continue = FALSE;
  347.                           break;
  348.  
  349.       case ANGLE_GAD    : angle = (ULONG)angle_string.LongInt;
  350.                           Continue = FALSE;
  351.                           break;
  352.  
  353.       case VELOCITY_GAD : velocity = (ULONG)(16-(velocity_prop.HorizPot >> 12));
  354.                           Continue = FALSE;
  355.                           break;
  356.  
  357.       case AIRFOIL_GAD  : if(mode) mode = FALSE;
  358.                           else mode = TRUE;
  359.                           Continue = FALSE;
  360.                           break;
  361.  
  362.       case TITLE_GAD    : if(title) title = FALSE;
  363.                           else title = TRUE;
  364.                           break;
  365.  
  366.       case CLOSE_GAD    : break;
  367.  
  368.       case QUIT_GAD     : close_things();
  369.                           exit(0);
  370.                           break;
  371.    }
  372.    return gadgid;
  373. }
  374.  
  375. do_about()
  376. {
  377.    int i;
  378.  
  379.    /*****************************************************/
  380.    /* This subroutine displays the initial information. */
  381.    /*****************************************************/
  382.  
  383.    SetAPen(rp,0L);
  384.    RectFill(rp,(long)(XMIN+1),(long)(YMIN+1),(long)(XMAX-1),(long)(YMAX-1));
  385.    SetAPen(rp,1L);
  386.    for(i = 0;i < 24;i++)
  387.    {
  388.       Move(rp,2L,(long)(8*i+8));
  389.       Text(rp,about[i],(long)strlen(about[i]));
  390.    }
  391. }
  392.  
  393. open_things()
  394. {
  395.    struct Library *OpenLibrary();
  396.    struct Screen *OpenScreen();
  397.    struct Window *OpenWindow();
  398.    struct ViewPort *ViewPortAddress();
  399.    BYTE *AllocRaster();
  400.    void * AllocMem();       /* FW for image data */
  401.  
  402.    if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L)))
  403.    {
  404.       printf("no graphics library!!!\n");
  405.       close_things();
  406.       exit(1);
  407.    }
  408.    mask |= GRAPHICS;
  409.  
  410.    if(!(IntuitionBase = (struct IntuitionBase *)
  411.         OpenLibrary("intuition.library",0L)))
  412.    {
  413.       printf("no intuition library!!!\n");
  414.       close_things();
  415.       exit(2);
  416.    }
  417.    mask |= INTUITION;
  418.  
  419.    if (!(s = OpenScreen(&ns)))
  420.    {
  421.       printf("could not open the screen\n");
  422.       close_things();
  423.       exit(3);
  424.    }
  425.    mask |= SCREEN;
  426.  
  427.    nw.Screen = s;
  428.  
  429.    if (!(w = OpenWindow(&nw)))
  430.    {
  431.       printf("could not open the window\n");
  432.       close_things();
  433.       exit(4);
  434.    }
  435.    mask |= WINDOW;
  436.  
  437.    rp = w->RPort;
  438.    vp = ViewPortAddress(w);
  439.  
  440.    InitArea(&area,buffer,250L);
  441.    rp->AreaInfo = &area;
  442.    trp.Size = (long)RASSIZE(640L,400L);
  443.  
  444.    if (!(trp.RasPtr = (BYTE *)AllocRaster(640L,400L)))
  445.    {
  446.       printf("could not allocate memory for area fills\n");
  447.       close_things();
  448.       exit(5);
  449.    }
  450.    mask |= AREAFILL;
  451.  
  452.    rp->TmpRas = &trp;
  453.  
  454. /* FW - make chip mem copy of gadget images */
  455.    if ( ! ( ChipImg = (struct ImageMem *)
  456.                         AllocMem ( CHIP_IMG_SIZ, MEMF_CHIP ) ) ) {
  457.       close_things();
  458.       exit(7);        /* note "7" is out of sequence */
  459.    }
  460.  
  461.    *ChipImg = gadgimgs; /* copy imagery to chip mem */
  462.  
  463.    quit_image.ImageData = &ChipImg->closeimage[0];  /* adjust pointers */
  464.    close_image.ImageData = &ChipImg->closeimage[0];
  465.    stream_image.ImageData = &ChipImg->streamimage[0];
  466.    pressure_image.ImageData = &ChipImg->pressureimage[0];
  467. /* FW - end of added code */
  468.  
  469.    LoadRGB4(vp,colors,16L);
  470.  
  471.    InitRequester(&AirRequest);
  472.    AirRequest.LeftEdge = 0L;
  473.    AirRequest.TopEdge = 0L;
  474.    AirRequest.Width = 200L;
  475.    AirRequest.Height = 150L;
  476.    AirRequest.RelLeft = -100L;
  477.    AirRequest.RelTop = -75L;
  478.    AirRequest.ReqGadget = &quit_gad;
  479.    AirRequest.Flags = POINTREL;
  480.    AirRequest.BackFill = 0;
  481.    
  482.    if (!(SetDMRequest(w,&AirRequest)))
  483.    {
  484.       printf("could not set Requester\n");
  485.       close_things();
  486.       exit(6);
  487.    }
  488.    mask |= DMREQUEST;
  489.  
  490.    ShowTitle(s,FALSE);
  491. }
  492.  
  493. close_things()
  494. {
  495.    if(mask & DMREQUEST) ClearDMRequest(w,&AirRequest);
  496.    if ( ChipImg ) FreeMem ( ChipImg, CHIP_IMG_SIZ );   /* FW */
  497.    if(mask & AREAFILL)  FreeRaster(trp.RasPtr,640L,400L);
  498.    if(mask & WINDOW)    CloseWindow(w);
  499.    if(mask & SCREEN)    CloseScreen(s);
  500.    if(mask & GRAPHICS)  CloseLibrary(GfxBase);
  501.    if(mask & INTUITION) CloseLibrary(IntuitionBase);
  502. }
  503.