home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1988 / 03 / feldline.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-01-06  |  9.7 KB  |  319 lines

  1. (* ----------------------------------------------------------------------- *)
  2. (*                              FELDLINE.PAS                               *)
  3.  
  4. PROGRAM Feldlinien;
  5.  
  6. CONST Pi     = 3.1415627;
  7.       e0     = 8.85E-12;
  8.       anzahl = 100;
  9.       xmax   = 639;
  10.       ymax   = 199;
  11.  
  12. TYPE point = RECORD  x,y :REAL;  END;
  13.  
  14. VAR maus_x,maus_y,anz_p,anz_n    :INTEGER;
  15.     maus_l,maus_r,maus_b,abbruch :BOOLEAN;
  16.     plus,minus,temp              :ARRAY [0..anzahl] OF point;
  17.     minus_p                      :ARRAY [0..anzahl] OF BOOLEAN;
  18.     er,q,fak,fx,fy,f,vektor,l    :REAL;
  19.     anz_lad                      :INTEGER;
  20.  
  21. (*$i GRAPH.P *)                         (* wird von Turbo Pascal benoetigt *)
  22.  
  23. (* ----------------------------------------------------------------------- *)
  24. (*                      Ermittlung der neuen Cursorposition                *)
  25.  
  26. PROCEDURE Maus;
  27.  
  28. VAR puffer :ARRAY [1..8,1..8] OF BYTE;
  29.     taste  :CHAR;
  30.  
  31. BEGIN
  32.   taste := ' ';  maus_l := FALSE;  maus_r := FALSE;  maus_b := FALSE;
  33.   WHILE NOT (taste IN ['.','-',',']) DO BEGIN
  34.     IF maus_x < 0 THEN maus_x  := 0;
  35.     IF maus_x > 632 THEN maus_x  := 632;
  36.     IF maus_y < 0 THEN maus_y := 0;
  37.     IF maus_y > 192 THEN maus_y := 192;
  38.                         (* Bildschirminhalt unter Cursor in Puffer sichern *)
  39.     getpic(puffer,maus_x,maus_y,maus_x+7,maus_y+7);
  40.                                       (* ... und Cursor als Pfeil zeichnen *)
  41.     draw(maus_x,maus_y+7,maus_x+7,maus_y,1);
  42.     draw(maus_x+7,maus_y+1,maus_x+3,maus_y+2,1);
  43.     draw(maus_x+6,maus_y+1,maus_x+7,maus_y+2,1);
  44.     WHILE NOT KeyPressed DO;                     (* auf Tastendruck warten *)
  45.     WHILE KeyPressed DO Read (Kbd,taste);         (* Tastaturpuffer leeren *)
  46.                               (* alten Bildschirminhalt wieder herstellen: *)
  47.     putpic(puffer,maus_x,maus_y+7);
  48.     CASE UpCase(taste) OF              (* "UpCase" liefert Grossbuchstaben *)
  49.       'F': maus_x := maus_x + 1;
  50.       'G': maus_x := maus_x + 16;
  51.       'S': maus_x := maus_x - 1;
  52.       'A': maus_x := maus_x - 16;
  53.       'E': maus_y := maus_y - 1;
  54.       '4': maus_y := maus_y - 8;
  55.       'C': maus_y := maus_y + 1;
  56.       'X': maus_y := maus_y + 8;
  57.       ELSE;
  58.     END;
  59.   END;
  60.   IF taste = '.' THEN maus_l := TRUE
  61.   ELSE IF taste = '-' THEN maus_r := TRUE
  62.   ELSE IF taste = ',' THEN maus_b := TRUE;
  63. END;
  64.  
  65. (* ----------------------------------------------------------------------- *)
  66. (*                         zeichnet Kreis mit r = 4                        *)
  67.  
  68. PROCEDURE Kreis (mx,my :INTEGER);
  69.  
  70. CONST r  =  4;
  71.  
  72. VAR alpha     :REAL;
  73.     x,y,ax,ay :INTEGER;
  74.  
  75. BEGIN
  76.   ax := mx-2*r;  ay := my;  alpha := -Pi;
  77.   WHILE alpha <= Pi DO BEGIN
  78.     x := mx+Trunc(2*r*Sin(alpha));
  79.     y := my+Trunc(r*Cos(alpha));
  80.     draw(ax,ay,x,y,1);
  81.     ax := x;  ay := y;
  82.     alpha := alpha+Pi/4;
  83.   END;
  84. END;
  85.  
  86. (* ----------------------------------------------------------------------- *)
  87. (*                         zeichnet positive Ladung                        *)
  88.  
  89. PROCEDURE Dr_Plus (mx,my :INTEGER);
  90.  
  91. BEGIN
  92.   Kreis(mx,my);
  93.   draw(mx-2,my,mx+2,my,1);
  94.   draw(mx,my-1,mx,my+1,1);
  95. END;
  96.  
  97. (*                         zeichnet negative Ladung                        *)
  98.  
  99. PROCEDURE Dr_Minus (mx,my :INTEGER);
  100.  
  101. BEGIN
  102.   Kreis(mx,my);
  103.   draw(mx-2,my,mx+2,my,1);
  104. END;
  105.  
  106. (* ----------------------------------------------------------------------- *)
  107. (*                           Bedienungsanleitung                           *)
  108.  
  109. PROCEDURE Erklaerung;
  110.  
  111. BEGIN
  112.   ClrScr;                                           (* Bildschirm loeschen *)
  113.   WriteLn('***************************************',
  114.           '***************************************');
  115.   WriteLn;
  116.   WriteLn('      F e l d l i n i e n  1.0       ',
  117.           '(C) 1988  Michael Smy & PASCAL INT.');
  118.   WriteLn;
  119.   WriteLn('***************************************',
  120.           '***************************************');
  121.   WriteLn;
  122.   WriteLn('Dieses Programm stellt die Feldlinien eines',
  123.           ' elektrischen Feldes dar. Es können');
  124.   WriteLn('beliebig viele positive und negative Ladungen',
  125.           ' mit einem Graphik-Cursor eingege-');
  126.   WriteLn('ben  werden. Dieser wird folgendermaßen bedient:');
  127.   WriteLn;
  128.   WriteLn('                                      4 - schnell nach oben');
  129.   WriteLn;
  130.   WriteLn('                                      e - langsam nach oben');
  131.   WriteLn;
  132.   WriteLn('           schnell nach links - a   s   f   g -',
  133.           ' schnell nach rechts');
  134.   WriteLn('                langsam nach links /     \ langsam nach rechts');
  135.   WriteLn('                                      c - langsam nach unten');
  136.   WriteLn;
  137.   WriteLn('                                      x - langsam nach oben');
  138.   WriteLn;
  139.   WriteLn('"." ergibt eine positive Ladung, "-" eine negative.');
  140.   WriteLn('"," beendet die eingabe und leitet die Berechnung ein.');
  141.   WriteLn;
  142.   Write('Dielektrizitätszahl des Mediums (Luft: 1)  ? ');  ReadLn(er);
  143.   WriteLn;
  144.   Write('Gewünschte Ladung einer Einzelladung in Cb ? ');  ReadLn(q);
  145.   q := q*q;
  146.   WriteLn;
  147.   Write('Grundlänge des zu berechnenden Kraftvektor ? ');  ReadLn(vektor);
  148.   WriteLn;
  149.   REPEAT
  150.     Write('Wieviele Probeladungen sollen pro Ladung abgeschickt werden ? ');
  151.     ReadLn(anz_lad);
  152.   UNTIL anz_lad >= 1;
  153.   IF 4 * Pi * e0 * er = 0 THEN Erklaerung ELSE fak := q/(4*Pi*e0*er);
  154. END;
  155.  
  156. (* ----------------------------------------------------------------------- *)
  157. (*                      Eingabe der Ladungsverteilung                      *)
  158.  
  159. PROCEDURE eingabe;
  160.  
  161. BEGIN
  162.   hires;                                       (* Graphik-Modus aktivieren *)
  163.   anz_p := 0;  anz_n := 0;
  164.   Maus;
  165.   WHILE NOT maus_b DO BEGIN
  166.     IF maus_l THEN BEGIN
  167.       Dr_Plus(maus_x+7,maus_y);
  168.       plus[anz_p].x := maus_x+7;
  169.       plus[anz_p].y := maus_y;
  170.       anz_p := anz_p+1;
  171.     END
  172.     ELSE IF maus_r THEN BEGIN
  173.       Dr_Minus(maus_x+7,maus_y);
  174.       minus[anz_n].x := maus_x+7;
  175.       minus[anz_n].y := maus_y;
  176.       minus_p[anz_n] := FALSE;
  177.       anz_n := anz_n+1;
  178.     END;
  179.     Maus;
  180.   END;
  181.   anz_p := anz_p-1;
  182.   anz_n := anz_n-1;
  183. END;
  184.  
  185. (* ----------------------------------------------------------------------- *)
  186. (*                      Berechnung der Kraft auf Ladung                    *)
  187.  
  188. PROCEDURE kraft (positiv: BOOLEAN; p: point);
  189.  
  190. VAR r,r3,h_x,h_y :REAL;
  191.     iii          :INTEGER;
  192.  
  193. BEGIN
  194.   fx := 0;  fy := 0;
  195.   FOR iii := 0 TO anz_p DO BEGIN
  196.     h_x := plus[iii].x-p.x;  h_y := plus[iii].y-p.y;
  197.     r := Sqrt(h_x*h_x+h_y*h_y);  r3 := r*r*r;
  198.     IF r <> 0 THEN
  199.       IF positiv THEN BEGIN
  200.         fx := fx-fak*h_x/r3;  fy := fy-fak*h_y/r3;
  201.       END
  202.       ELSE BEGIN
  203.         fx := fx-fak*h_x/r3;  fy := fy-fak*h_y/r3;
  204.       END;
  205.     IF NOT positiv THEN
  206.       IF r <= vektor THEN abbruch := TRUE;
  207.   END;
  208.   FOR iii := 0 TO anz_n DO BEGIN
  209.     h_x := minus[iii].x-p.x;  h_y := minus[iii].y-p.y;
  210.     r := Sqrt(h_x*h_x+h_y*h_y);  r3 := r*r*r;
  211.     IF r <> 0 THEN
  212.       IF positiv THEN BEGIN
  213.         fx := fx+fak*h_x/r3;  fy := fy+fak*h_y/r3;
  214.       END
  215.       ELSE BEGIN
  216.         fx := fx-fak*h_x/r3;  fy := fy-fak*h_y/r3;
  217.       END;
  218.     IF positiv THEN
  219.       IF r <= l THEN BEGIN
  220.         abbruch := TRUE;
  221.         minus_p[iii] := TRUE;
  222.       END;
  223.   END;
  224.   f := Sqrt(fx*fx+fy*fy);
  225. END;
  226.  
  227. (* ----------------------------------------------------------------------- *)
  228. (*                   Zeichnen einer Linie von p1 nach p2                   *)
  229. PROCEDURE Line (p1,p2: point);
  230.  
  231. BEGIN
  232.   draw(Trunc(p1.x),Trunc(p1.y),Trunc(p2.x),Trunc(p2.y),1);
  233. END;
  234.  
  235. (* ----------------------------------------------------------------------- *)
  236. (*                    Zeichnen des Wegs einer Probeladung                  *)
  237.  
  238. PROCEDURE zeichne (posneg: BOOLEAN; start :point);
  239.  
  240. VAR i          :INTEGER;
  241.     pr,vor,alt :point;
  242.     f_alt      :REAL;
  243.  
  244. BEGIN
  245.   l := vektor;
  246.   pr.x := start.x;
  247.   pr.y := start.y;
  248.   WHILE (pr.x >= 0) AND (pr.x <= xmax) AND (pr.y >= 0) AND (pr.y <= ymax)
  249.   AND NOT abbruch DO BEGIN
  250.     kraft(posneg,pr);
  251.     IF f < 1E-9 THEN pr.x := -1
  252.     ELSE BEGIN
  253.       vor.x := pr.x+fx*l/2/f;
  254.       vor.y := pr.y+fy*l/2/f;
  255.       f_alt := f;
  256.       kraft(posneg,vor);
  257.       IF f < 1E-9 THEN pr.x := -1
  258.       ELSE BEGIN
  259.         alt.x := pr.x+fx*l/f;
  260.         alt.y := pr.y+fy*l/f;
  261.         Line(pr,alt);
  262.         pr.x := alt.x;  pr.y := alt.y;
  263.         IF f <> f_alt THEN l := vektor*1e8*l/2/abs(f-f_alt)
  264.         ELSE l := vektor*2;
  265.         IF l < vektor/2 THEN l := vektor/2;
  266.         IF l > vektor*2 THEN l := vektor*2;
  267.       END;
  268.     END;
  269.   END;
  270. END;
  271.  
  272. (* ----------------------------------------------------------------------- *)
  273. (*                  Berechnen und Zeichnen der Feldlinien                  *)
  274.  
  275. PROCEDURE berechnung;
  276.  
  277. VAR i,ii    :INTEGER;
  278.     pr,alt  :point;
  279.     sal,cal :REAL;
  280.     poslad  :BOOLEAN;
  281.  
  282.   PROCEDURE rechne;
  283.   BEGIN
  284.     kraft(poslad,plus[i]);
  285.     IF f <> 0 THEN BEGIN
  286.       alt.x := fx*5/f;
  287.       alt.y := fy*5/f;
  288.       FOR ii := 1 TO anz_lad DO BEGIN
  289.         abbruch := FALSE;
  290.         pr.x := temp[i].x+alt.x;  pr.y := temp[i].y+alt.y;
  291.         zeichne(poslad,pr);
  292.         pr.x := alt.x*cal-alt.y*sal;
  293.         pr.y := alt.x*sal+alt.y*cal;
  294.         alt.x := pr.x;
  295.         alt.y := pr.y;
  296.       END;
  297.     END;
  298.   END;
  299.  
  300. BEGIN
  301.   sal := Sin(2*Pi/anz_lad);  cal := Cos(2*Pi/anz_lad);
  302.   temp := plus;              poslad := TRUE;
  303.   FOR i := 0 TO anz_p DO rechne;
  304.   temp := minus;             poslad := FALSE;
  305.   FOR i := 0  TO anz_n DO
  306.     IF NOT(minus_p[i]) THEN rechne;
  307. END;
  308.  
  309. (* ----------------------------------------------------------------------- *)
  310.  
  311. BEGIN (* Feldlinien *)
  312.   maus_x := 319;  maus_y := 99;
  313.   Erklaerung;
  314.   eingabe;
  315.   berechnung;
  316.   WHILE NOT KeyPressed DO;                       (* auf Tastendruck warten *)
  317.   textmode;
  318. END.
  319.