#!/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('', sub {pause()}); $mw->bind('', sub {$mw->destroy()}); $mw->bind('', 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); } }