home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1991 / 07_08 / praxis / windmess / windgame.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1991-06-06  |  9.4 KB  |  264 lines

  1. (* ------------------------------------------------------ *)
  2. (*                      WINDGAME.PAS                      *)
  3. (*          Windgeschwindigkeit und Windrichtung          *)
  4. (*                messen mit der Gamekarte                *)
  5. (*                  für Hercules und VGA                  *)
  6. (*           (c) 1991 Andreas Bartels & TOOLBOX           *)
  7. (* ------------------------------------------------------ *)
  8. PROGRAM WindGame;
  9.  
  10. USES Crt, Dos, Graph;
  11.  
  12. VAR
  13.   Anfang                       : BOOLEAN;
  14.   Xa, Ya, Beaufort             : WORD;
  15.   GraphDriver, GraphMode,
  16.   X0, Y0, XOff, YOff,
  17.   i, NMittelung                : INTEGER;
  18.   MaxNord, MaxOst,
  19.   TanAlphaY, TanAlphaX,
  20.   Alpha, RKugel, YFak,
  21.   KugelFlaeche, KugelMasse,
  22.   Temperatur, LuftDruck,
  23.   RelFeuchte, LuftDichte,
  24.   GPX, GPY, AlphaX, AlphaY,
  25.   VX, VY, VXAlt, VYAlt, V,
  26.   Richtung, OffX, OffY, cw, g,
  27.   FaktX, FaktY, V_aus_Alpha    : REAL;
  28.   HStr                         : STRING[10];
  29.  
  30. CONST
  31.   DaumenNS : REAL = 0.0;  { Daumenfaktor Nord-Süd-Richtung }
  32.   DaumenWO : REAL = 0.0;  { Daumenfaktor Ost-West-Richtung }
  33.    { diese Konstanten sind hardwareabhängig und müssen auf }
  34.    { jedem Rechner individuell gesetzt werden!             }
  35.  
  36. FUNCTION GamePort(Kanal : BYTE;
  37.                   Offset : INTEGER) : INTEGER;
  38.        { Kanal: 0/1/2/3 = 1X/1Y/2X/2Y = SelectBit: 1/2/4/8 }
  39. CONST
  40.   MaxZaehler = 2000;
  41.   PortNr     = $201;
  42. VAR
  43.   SelectBit       : BYTE;
  44.   GPWert, Zaehler : INTEGER;
  45. BEGIN
  46.   INLINE($FA);                        { Interrupts sperren }
  47.   SelectBit := 1 SHL Kanal;
  48.   Zaehler := 0;
  49.   REPEAT
  50.     GPWert := Port[PortNr];
  51.     Inc(Zaehler);
  52.   UNTIL (GPWert AND SelectBit = 0)
  53.      OR (Zaehler >= MaxZaehler);
  54.   Port[PortNr] := GPWert;
  55.   Zaehler := Offset;
  56.   REPEAT
  57.     GPWert := Port[PortNr];
  58.     Inc(Zaehler);
  59.   UNTIL (GPWert AND SelectBit = 0)
  60.      OR (Zaehler >= MaxZaehler);
  61.   GamePort := Zaehler;
  62.   INLINE($FB);                       { Interrupts zulassen }
  63. END; { GamePort }
  64.  
  65. BEGIN
  66.                        { Festlegung der mechanischen Werte }
  67.   RKugel        := 0.032;                     { Radius [m] }
  68.   KugelMasse    := 0.050;               { Kugel-Masse [kg] }
  69.   KugelFlaeche  := Pi * Sqr(RKugel);    { Kugelfläche [m²] }
  70.   cw            := 0.33;          { Luftwiderstandsbeiwert }
  71.   g             := 9.81;     { Erdbeschleunigung    [m/s²] }
  72.   Temperatur    := 20.00;               { auch meßbar [°C] }
  73.   LuftDruck     := 101.30;                         { [KPa] }
  74.   RelFeuchte    := 70.00;           { rel. LuftFeuchte [%] }
  75.   LuftDichte    := 1.188 + 0.012 * (LuftDruck - 100) -
  76.                    0.004*(Temperatur-20);      { Näherung! }
  77.   VXAlt         :=  0;                             { [m/s] }
  78.   VYAlt         :=  0;                             { [m/s] }
  79.   X0            :=  164;                 { Windrosen-Mitte }
  80.   Y0            :=  163;                 { Windrosen-Mitte }
  81.   MaxNord       :=   32;          { Winkel zur Eichung [°] }
  82.   MaxOst        :=   35;          { Winkel zur Eichung [°] }
  83.   NMittelung    :=   20;          { Anzahl der Mittelungen }
  84.   V_aus_Alpha   :=   (2 * KugelMasse * g) /
  85.                      (LuftDichte * cw * KugelFlaeche);
  86.   Anfang := TRUE;
  87.   ClrScr;
  88.   WriteLn('WindGame' +
  89.           '    Windmessung am Gameport' +
  90.           '    (c) 1991 Andreas Bartels & toolbox');
  91.   WriteLn;
  92.   WriteLn('Bitte Meßwerk in Neutralstellung bringen ' +
  93.           'und <Return> drücken');
  94.   ReadLn;
  95.   XOff := -GamePort(0, 0);
  96.   YOff := -GamePort(1, 0);
  97.   WriteLn('Bitte Meßwerk auf Endstellung Nord ' +
  98.           'stellen und <Return> drücken.');
  99.   ReadLn;
  100.   FaktY := -MaxNord * Pi / 180 / GamePort(1, YOff);
  101.   WriteLn('Bitte Meßwerk auf Endstellung  Ost ' +
  102.           'stellen und <Return> drücken.');
  103.   ReadLn;
  104.   FaktX := MaxOst * Pi / 180 / GamePort(0, XOff);
  105.   WriteLn(' XOff : ', XOff:4, '  YOff : ', YOff:4,
  106.           '  FaktX : ', FaktX:7:5,
  107.           '  FaktY : ', FaktY:7:5, ' > <Return> drücken');
  108.   ReadLn;
  109.   GraphDriver := Detect;
  110.   InitGraph(GraphDriver, GraphMode, GetEnv('BGIPATH'));
  111.   { Pfad zu den BGI-Treibern mit "SET BGIPATH=..." setzen! }
  112.   GetAspectRatio(Xa, Ya);
  113.   YFak := Xa / Ya;
  114.   X0 := 164;
  115.   Y0 := 163;
  116.   OutTextXY(15, 7, 'WINDGAME: Windmessung am Gameport' +
  117.             '          (c) 1991 Andreas Bartels & toolbox');
  118.   Rectangle(0, 0, 639, 347);
  119.   Rectangle(0, 0, 639, 20);
  120.   Rectangle(331, 20, 639, 347);
  121.   SetViewPort(350, 30, 620, 347, TRUE);
  122.   OutTextXY(0, 20, '   Luft   ');
  123.   OutTextXY(0, 50, 'Temperatur      :          °C    ');
  124.   OutTextXY(0, 70, 'Druck           :          KPa   ');
  125.   OutTextXY(0, 90, 'Feuchtigkeit    :          % rel.');
  126.   OutTextXY(0, 110, '=> Dichte       :          kg/m^3');
  127.   OutTextXY(0, 170, '   Wind   ');
  128.   OutTextXY(0, 200, 'Geschwindigkeit :          m /s  ');
  129.   OutTextXY(0, 220, '                  =        Km/h  ');
  130.   OutTextXY(0, 240, 'Windstärke (Beaufort):           ');
  131.   OutTextXY(0, 260, 'in Richtung     :          Grad  ');
  132.                               { Windrosen-Anzeige aufbauen }
  133.   SetViewPort(1, 21, 330, 346, TRUE);
  134.   Circle(X0, Y0, 5);
  135.   FOR i := 1 TO 3 DO
  136.     Circle(X0, Y0, i*50);
  137.   FOR i := 0 TO 8 DO
  138.     Line(X0 + Round(144 * Cos(i * Pi / 4)),
  139.          Y0 + Round(144 * YFak * Sin(i * Pi / 4)),
  140.          X0 + Round(150 * Cos(i * Pi / 4)),
  141.          Y0 + Round(150 * YFak * Sin(i * Pi / 4)));
  142.   FOR i := 0 TO 72 DO
  143.     Line(X0 + Round(148 * Cos(i * Pi / 36)),
  144.          Y0 + Round(148 * YFak * Sin(i * Pi / 36)),
  145.          X0 + Round(150 * Cos(i * Pi / 36)),
  146.          Y0 + Round(150 * YFak * Sin(i * Pi / 36)));
  147.   OutTextXY(X0 - 3, Y0 - Trunc(159 * YFak), 'N');
  148.   OutTextXY(X0 + 154, Y0 - 3, 'O');
  149.   OutTextXY(X0 - 3, Y0 + Trunc(154 * YFak), 'S');
  150.   OutTextXY(X0 - 159, Y0 - 3, 'W');
  151.   SetWriteMode(XORPut);
  152.   SetColor(GetMaxColor);
  153.   REPEAT                     { Windmessung bis Tastendruck }    
  154.     GPX := 0;
  155.     GPY := 0;                    { gemittelte Werte bilden }
  156.     FOR i := 1 TO NMittelung DO BEGIN
  157.       GPX := GPX + GamePort(0, XOff);
  158.       GPY := GPY + GamePort(1, YOff);
  159.     END;
  160.     GPX := GPX / NMittelung + DaumenWO;
  161.     GPY := GPY / NMittelung + DaumenNS;
  162.     AlphaX := FaktX * GPX;         { Umrechnung Widerstand }
  163.     AlphaY := FaktY * GPY;         { in Winkel             }
  164.   { Umrechnung Winkel in Windrichtung und -geschwindigkeit }
  165.   { Sonderfälle : irgendwelche Winkel = 0                  }
  166.     IF (AlphaX = 0) AND (AlphaY = 0) THEN BEGIN
  167.       Richtung := -0.5 * Pi;
  168.       Alpha := 0;
  169.       V := 0;
  170.     END ELSE
  171.       IF AlphaX = 0 THEN BEGIN
  172.         Richtung := -0.5 * Pi;
  173.         IF AlphaY > 0 THEN
  174.           Richtung := 0.5 * Pi;
  175.         Alpha := -AlphaY;
  176.         IF AlphaY > 0 THEN
  177.           Alpha := AlphaY
  178.       END
  179.     ELSE
  180.       IF AlphaY = 0 THEN BEGIN
  181.         Richtung := 0;
  182.         Alpha := AlphaX;
  183.       END
  184.     ELSE BEGIN                                { Normalfall }
  185.       TanAlphaY := Sin(AlphaY) / Cos(AlphaY);
  186.       TanAlphaX := Sin(AlphaX) / Cos(AlphaX);
  187.       Richtung := ArcTan(TanAlphaY / TanAlphaX);
  188.       Alpha := ArcTan(TanAlphaX / Cos(Richtung));
  189.     END;
  190.     IF Alpha <> 0 THEN
  191.       V := Sqrt(Abs(Sin(Alpha) * V_aus_Alpha)) *
  192.            Alpha/Abs(Alpha);
  193.     VX := V * Cos(Richtung);
  194.     VY := V * Sin(Richtung);
  195.     Richtung := 90 + 180 / Pi * Richtung;        { in Grad }
  196.     IF VX < 0 THEN
  197.       Richtung := Richtung + 180;
  198.     IF Richtung = 360 THEN
  199.       Richtung := 0;
  200.     V := Abs(V);
  201.                  { Berechnung der Windstärke nach Beaufort }
  202.     CASE Round(V * 10) OF
  203.       0..3     : Beaufort := 0;
  204.       4..16    : Beaufort := 1;
  205.       17..34   : Beaufort := 2;
  206.       35..55   : Beaufort := 3;
  207.       56..80   : Beaufort := 4;
  208.       81..108  : Beaufort := 5;
  209.       109..139 : Beaufort := 6;
  210.       140..172 : Beaufort := 7;
  211.       173..208 : Beaufort := 8;
  212.       209..245 : Beaufort := 9;
  213.       246..285 : Beaufort := 10;
  214.       286..326 : Beaufort := 11;
  215.     ELSE
  216.       Beaufort := 12;
  217.     END;
  218.           { Konstanten, die auch als Variablen meßbar sind }
  219.     IF Anfang THEN BEGIN
  220.       SetViewPort(515, 30, 560, 220, TRUE);
  221.       ClearViewPort;
  222.       Str(Temperatur:5:2, HStr);
  223.       OutTextXY(0, 50, HStr);
  224.       Str(LuftDruck:5:1, HStr);
  225.       OutTextXY(0, 70, HStr);
  226.       Str(RelFeuchte:5:2, HStr);
  227.       OutTextXY(0, 90, HStr);
  228.       Str(LuftDichte:5:3, HStr);
  229.       OutTextXY(0, 110, HStr);
  230.     END;
  231.                             { Geschwindigkeit und Richtung }
  232.     IF (VXAlt <> VX) OR (VYAlt <> VY) THEN BEGIN
  233.       SetViewPort(515, 230, 560, 320, TRUE);
  234.       ClearViewPort;
  235.       Str(V:5:0, HStr);
  236.       OutTextXY(0, 0, HStr);
  237.       Str((V * 3.6):5:0, HStr);
  238.       OutTextXY(0, 20, HStr);
  239.       Str(Beaufort:5, HStr);
  240.       OutTextXY(0, 40, HStr);
  241.       Str(Richtung:5:0, HStr);
  242.       OutTextXY(0, 60, HStr);
  243.       GPX := GPX + GamePort(0, XOff);
  244.       GPY := GPY + GamePort(1, YOff);
  245.       SetViewPort(1, 21, 330, 346, TRUE);
  246.       IF NOT Anfang THEN BEGIN       { alten Pfeil löschen }
  247.         MoveTo(X0 + Round(3.6 * VXAlt),
  248.                Y0 + Round(3.6 * YFak * VYAlt));
  249.         LineTo(X0, Y0);
  250.       END;
  251.         MoveTo(X0 + Round(3.6 * VX),{ neuen Pfeil zeichnen }
  252.                Y0 + Round(3.6 * YFak * VY));
  253.       LineTo(X0, Y0);
  254.       Anfang := FALSE;
  255.     END;
  256.     VXAlt := VX;
  257.     VYAlt := VY;
  258.   UNTIL KeyPressed;
  259.   CloseGraph;
  260. END.
  261. (* ------------------------------------------------------ *)
  262. (*               Ende von WINDGAME.PAS                    *)
  263.  
  264.