Thread Agnesi - Netter Programmierspaß
(4 answers)
Opened by hlubenow at 2014-05-18 01:58
Keine Sorge, Perl kommt schon noch. ;)
Ideen, was man mal so programmieren kann (vielleicht auch sowas wie "Projekt Euler") können doch ruhig nach "Allgemeines", finde ich. Umstricken braucht ihr nicht (wenn ihr nicht wollt), meist mach' ich das selbst, wenn die Zeit dafür da ist. Hier also noch eine Perl-Übersetzung meiner Version: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 #!/usr/bin/perl use warnings; use strict; use Tk; use Math::Trig; # Screen resolution: my $RESX = 800; my $RESY = 600; # Zoom-factor and Up/Down-correction: my $XFAC = 70; my $XSUM = $RESX / 2; my $YFAC = 60; my $YSUM = $RESY / 2; my $mw = MainWindow -> new(); $mw -> optionAdd(font => "Arial 12 normal"); $mw -> title("Agnesi"); $mw -> geometry("+90+45"); my $cv = $mw->Canvas(-bg => "white", -width => $RESX, -height => $RESY); $cv->pack(); my $btn = $mw->Button(-text => "Ok", -command => sub {$mw ->destroy()}); $mw->bind('<Key-space>', sub {pause()}); $mw->bind('<Return>', sub {$mw->destroy()}); $mw->bind('<Control-q>', sub {$mw->destroy()}); $btn->pack(-side => 'right', -padx => 10, -pady => 10); my $angle = 130; my %points = ("up" => [cos(deg2rad(270)), sin(deg2rad(270))], "down" => [cos(deg2rad(90)), sin(deg2rad(90))], "circle" => [cos(deg2rad($angle)), sin(deg2rad($angle))], "upline" => [0, 0], "downline" => [0, 0], "curve" => [0, 0]); my @withdraw = []; drawStatic(); calculatePoints(); drawDynamic(); my $running = -1; $mw->after(1000, \&run); $mw->MainLoop(); sub drawStatic { $cv->createLine(0, $points{up}[1] * $YFAC + $YSUM, $RESX, $points{up}[1] * $YFAC + $YSUM); $cv->createLine(0, $points{down}[1] * $YFAC + $YSUM, $RESX, $points{down}[1] * $YFAC + $YSUM); $cv->createOval(($points{up}[0] - cos(deg2rad(0))) * $XFAC + $XSUM, $points{up}[1] * $YFAC + $YSUM, ($points{up}[0] + cos(deg2rad(0))) * $XFAC + $XSUM, $points{down}[1] * $YFAC + $YSUM); plotDot($points{down}, 0); } sub plotDot { my $wd = pop; my @point = @{$_[0]}; @point = @{getZoom(@point)}; my $o = $cv->createOval($point[0] - 5, $point[1] - 5, $point[0] + 5, $point[1] + 5, -fill => 'black'); if ($wd) { push(@withdraw, $o); } } sub drawLine { my @from_ = @{$_[0]}; my @to_ = @{$_[1]}; @from_ = @{getZoom(@from_)}; @to_ = @{getZoom(@to_)}; my $o = $cv->createLine($from_[0], $from_[1], $to_[0], $to_[1]); push(@withdraw, $o); } sub plotPoint { my @point = @{$_[0]}; @point = @{getZoom(@point)}; $cv->createLine($point[0], $point[1], $point[0] + 1, $point[1] + 1); } sub getZoom { return [$_[0] * $XFAC + $XSUM, $_[1] * $YFAC + $YSUM]; } sub calculatePoints { $points{circle} = [cos(deg2rad($angle)), sin(deg2rad($angle))]; # Strahlensatz: # # ## # # # # # # # # # # # # # # # # # # # # # my $d = $points{up}[1] - $points{down}[1]; my $a = $points{circle}[1] - $points{down}[1]; my $b = $points{down}[0] - $points{circle}[0]; $points{upline} = [$points{down}[0] - $d / $a * $b, $points{up}[1]]; $points{downline} = [$points{upline}[0], $points{down}[1]]; $points{curve} = [$points{upline}[0], $points{circle}[1]]; } sub drawDynamic { drawLine($points{down}, $points{upline}); drawLine($points{upline}, $points{downline}); drawLine($points{curve}, $points{circle}); plotDot($points{circle}, 1); plotDot($points{upline}, 1); plotDot($points{downline}, 1); plotDot($points{curve}, 1); plotPoint($points{curve}); } sub run { $running = 1; draw(); } sub pause { $running *= -1; if ($running == 1) { draw(); } } sub draw { if ($running == -1) { return; } if ($angle <= 410) { $cv->delete(@withdraw); calculatePoints(); drawDynamic(); $angle += 1; $mw->after(50, \&draw); } } Perl/Tk führt bei mir meist dazu, daß ich recht viele globale Variablen verwende, die dann in allen Funktionen bekannt sind. Wenn das Programm nicht wirklich groß ist, ist das vielleicht gar nicht so schlimm. Hier hab' ich auch die Daten (für die Punkte) in einer globalen Variable (HoA). Ist hier eigentlich ganz praktisch, obwohl globale Variablen allgemein ja eher verpönt sind ... modedit Editiert von pq: more-tag hinzugefügt Last edited: 2014-05-19 11:14:02 +0200 (CEST) |