100) ){ $anz=6; } } else { $anz=6; } # runden auf wieviel Stellen / rounding to how many digits if(isset($_GET['rnd'])) { $runden=$_GET['rnd']; if (($runden < 0)OR($runden > 4) ){ $runden=2; } } else { $runden=2; } if(isset($_GET['ani'])) { $ani=$_GET['ani']; if (($ani < 2)OR($ani > 20) ){ $ani=6; } } else { $ani=6; } # Zeichenketten vorbereiten / prepare strings ... $pfa=""; $pf=""; $pfas=""; $pfs=""; $rr=0; $ccx=0; $ccy=0; # Animation values ... for ($k = 1; $k <= $ani; $k++) { # Parameter ... $phideg=mt_rand(-1000,1000); $thetadeg=mt_rand(-1000,1000); $deltadeg=mt_rand(-1000,1000); $rx=mt_rand(-300,300); $ry=mt_rand(-300,300); $cx=mt_rand(300,700); $cy=mt_rand(300,700); # Auswertung beginnen: # (start evaluation) $rx=abs($rx); $ry=abs($ry); $phideg=fmod($phideg,360); $thetadeg=fmod($thetadeg,360); $deltadeg=fmod($deltadeg,360); $phi=$phideg*M_PI/180; $theta=$thetadeg*M_PI/180; $delta=$deltadeg*M_PI/180; $ca=cos($phi); $sa=sin($phi); $xh1=$rx*cos($theta); $yh1=$ry*sin($theta); $xh2=$rx*cos($theta+$delta); $yh2=$ry*sin($theta+$delta); $x1=round($ca*$xh1-$sa*$yh1+$cx,$runden); $y1=round($sa*$xh1+$ca*$yh1+$cy,$runden); $x2=round($ca*$xh2-$sa*$yh2+$cx,$runden); $y2=round($sa*$xh2+$ca*$yh2+$cy,$runden); if (abs($deltadeg)>180) { $fA = 1; } else { $fA = 0; } if ($deltadeg>0) { $fS = 1; } else { $fS = 0; } $pfad="M$x1,$y1 A$rx,$ry $phideg $fA,$fS $x2,$y2"; ################################# # Datensatz erzeugen / Interpolation $dphi=$delta/$anz; for ($j = 0; $j <= $anz; $j++) { $tt=$dphi*$j; $cpi=cos($tt+$theta); $spi=sin($tt+$theta); # Punkte / points $xx=$rx*$cpi; $yy=$ry*$spi; # Ableitungen / derivatives ... $dx=-$dphi*$rx*$spi; $dy=$dphi*$ry*$cpi; # rotieren / rotate $data[$j][0]=$ca*$xx-$sa*$yy+$cx; $data[$j][1]=$sa*$xx+$ca*$yy+$cy; $data[$j][2]=$ca*$dx-$sa*$dy; $data[$j][3]=$sa*$dx+$ca*$dy; } # Aus den Ableitungen die Kontrollpunkte berechnen # (generate control points from derivatives) $cp[0][0]=round($data[0][0]+$data[0][2]/3,$runden); $cp[0][1]=round($data[0][1]+$data[0][3]/3,$runden); for ($j = 0; $j <= $anz; $j++) { $cq[$j][0]=round($data[$j][0]-$data[$j][2]/3,$runden); $cq[$j][1]=round($data[$j][1]-$data[$j][3]/3,$runden); # und nun erst Punkte runden / and now round points $data[$j][0]=round($data[$j][0],$runden); $data[$j][1]=round($data[$j][1],$runden); } # Daraus Pfad bestimmen und malen der Punkte vorbereiten # (generate path data and prepare for painting) $pfada='M'.$data[0][0].' '.$data[0][1].' C'.$cp[0][0].' '.$cp[0][1].' '.$cq[1][0].' '.$cq[1][1].' '.$data[1][0].' '.$data[1][1]." S\n"; for ($j = 2; $j <=$anz; $j++) { $pfada.=$cq[$j][0].' '.$cq[$j][1].' '.$data[$j][0].' '.$data[$j][1]."\n"; } ################################### # values $pfa.='; '.$pfada." \n"; $pf.='; '.$pfad." \n"; $pfas.=$pfada." \n"; $pfs.=$pfad." \n"; # viewBox zentrieren vorbereiten / prepare to center the viewBox $rr=max($rr,$rx,$ry); $ccx=$ccx+$cx; $ccy=$ccy+$cy; } $ccx=$ccx/$ani; $ccy=$ccy/$ani; $pfa=$pfada.$pfa; $pf=$pfad.$pf; $aus=" Approximierter Pfad - Animationswerte / Approximated Path - animation values Pfad - Animationswerte / Path - animation values Approximierter Pfad / Approximated Path Pfad / Path "; # viewBox berechnen / calculate viewBox $vv=max(4*$rr,400); $vh=1.5*$vv; $vy=round($ccy-$vv/2); $vx=round($ccx-$vh/2); $viewBox="$vx $vy $vh $vv"; # svg-header senden: $content="Content-type: image/svg+xml; charset=iso-8859-1"; header($content); # xml-Zeile ausgeben echo ""; # und jetzt das Dokument ?> SVG: Vergleich Animation elliptischer Bogen und approximierter elliptischer Bogen / Comparison Animation Elliptical Arc and Approximated Elliptical Arc Für values-Animationen werden elliptische Bögen zufällig gewählt (grau) und alternativ auch mit kubischen Kurven genähert (grün). Die Animationen werden miteinander verglichen. Die einzelnen Werte der Animation sind als dünne Kurven dargestellt. Wie zu erwarten, sind die genäherten Kurven nur bei den ausgewählten Werten elliptische Bögen, nicht dazwischen. Mit dem GET-Parameter 'anz' kann die Anzahl der Interpolationspunkte angegeben werden, Voreinstellung ist 6 (Bereich 2 bis 100). 'rnd' gibt an, auf wieviele Stellen gerundet wird, Voreinstellung ist 2 (Bereich 0 bis 4). 'ani' gibt an, wieviele Animationswerte gewählt werden, Voreinstellung ist 6 (Bereich 2 bis 20). For a values animation elliptical arcs are choosen randomly (gray) and alternatively approximated with a cubic curve (green). The animations are compared with each other. The values of the animation itself are presented with thin curves. As expected the approximated curves are only elliptical arcs at the choosen values, not between. With the GET parameter 'anz' the number of interpolation points can be given, default is 6 (range 2 to 100). 'rnd' are the digits to be rounded in the fractional part of numbers in the output, default is 2 (range 0 to 4). 'ani' are the number of animation values, default is 6 (range 2 to 20)