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; } # Parameter ... if(isset($_GET['phi'])) { $phideg=$_GET['phi']; if (($phideg < -32767.9999)OR($phideg > 32767.9999) ){ $phideg=mt_rand(-1000,1000); } } else { $phideg=mt_rand(-1000,1000); } if(isset($_GET['fA'])) { $fA=$_GET['fA']; if ($fA!=0){ $fA=1; } } else { $fA=mt_rand(0,1); } if(isset($_GET['fS'])) { $fS=$_GET['fS']; if ($fS!=0){ $fS=1; } } else { $fS=mt_rand(0,1); } if(isset($_GET['rx'])) { $rx=$_GET['rx']; if (($rx < -32767.9999)OR($rx > 32767.9999) ){ $rx=mt_rand(-300,300); } } else { $rx=mt_rand(-300,300); } if(isset($_GET['ry'])) { $ry=$_GET['ry']; if (($ry < -32767.9999)OR($ry >32767.9999) ){ $ry=mt_rand(-300,300); } } else { $ry=mt_rand(-300,300); } if(isset($_GET['x1'])) { $x1=$_GET['x1']; if (($x1 < -32767.9999)OR($x1 > 32767.9999) ){ $x1=mt_rand(-600,600); } } else { $x1=mt_rand(-600,600); } if(isset($_GET['x2'])) { $x2=$_GET['x2']; if (($x2 < -32767.9999)OR($x2 > 32767.9999) ){ $x2=mt_rand(-600,600); } } else { $x2=mt_rand(-600,600); } if(isset($_GET['y1'])) { $y1=$_GET['y1']; if (($y1 < -32767.9999)OR($y1 > 32767.9999) ){ $y1=mt_rand(-600,600); } } else { $y1=mt_rand(-600,600); } if(isset($_GET['y2'])) { $y2=$_GET['y2']; if (($y2 < -32767.9999)OR($y2 > 32767.9999) ){ $y2=mt_rand(400,600); } } else { $y2=mt_rand(400,600); } $pfad="M$x1,$y1 A$rx,$ry $phideg $fA,$fS $x2,$y2"; # Auswertung beginnen: # (start evaluation) $rx=abs($rx); $ry=abs($ry); $phideg=fmod($phideg,360); $phi=$phideg*M_PI/180; $ca=cos($phi); $sa=sin($phi); # rechnen oder nicht? # to calculate or not to calculate? $flag1=($rx*$ry>0); $flag2=(!(($x1==$x2) AND ($y1==$y2))); $flag= ($flag1 AND $flag2); if ($flag) { $xs1=0.5*($ca*($x1-$x2) + $sa*($y1-$y2)); $ys1=0.5*(-$sa*($x1-$x2) + $ca*($y1-$y2)); # Kontrollieren, ob rx und ry skaliert werden müssen: # (check whether rx and ry have to be scaled or not) $lambda=sqrt($xs1*$xs1/$rx/$rx+$ys1*$ys1/$ry/$ry); if ($lambda > 1) { $rx=$lambda*$rx; $ry=$lambda*$ry; } # Mittelpunkt bestimmen: # (determine center) if ($fA==$fS) { $vor=-1; } else { $vor=1; } $wt1=$rx*$rx*$ry*$ry; $wt2=$rx*$rx*$ys1*$ys1+$ry*$ry*$xs1*$xs1; $wurzel=sqrt(max(0,$wt1/$wt2-1)); $cxs=$vor*$wurzel*$rx/$ry*$ys1; $cys=-$vor*$wurzel*$ry/$rx*$xs1; $cx=$ca*$cxs -$sa*$cys + ($x1+$x2)/2; $cy=$sa*$cxs +$ca*$cys + ($y1+$y2)/2; $cxp=round($cx,$runden); $cyp=round($cy,$runden); # Anfangs- und Endwinkel bestimmen # (determine initial and final angle) $xt1=$ca*($x1-$cx) + $sa*($y1-$cy); $yt1=-$sa*($x1-$cx) + $ca*($y1-$cy); $xt2=$ca*($x2-$cx) + $sa*($y2-$cy); $yt2=-$sa*($x2-$cx) + $ca*($y2-$cy); $th1=$xt1/$rx; $th2=$yt1/$ry; $th3=$xt2/$rx; $th4=$yt2/$ry; if($yt1>=0) { $vh=1; } else { $vh=-1; } if($yt2>=0) { $vg=1; } else { $vg=-1; } $theta1=$vh*acos($th1/sqrt($th1*$th1+$th2*$th2)); $theta2=$vg*acos($th3/sqrt($th3*$th3+$th4*$th4)); # Differenzwinkel und Laufrichtung # (difference angle and propagation direction) $dtheta=abs($theta2-$theta1); $dthetb=abs($dtheta-2*M_PI); if ($fA==1) { $dtheta=max($dtheta,$dthetb); } else { $dtheta=min($dtheta,$dthetb); } if ($fS==1) { $dtheta=$dtheta; } else { $dtheta=-$dtheta; } ################################# # Datensatz erzeugen / Interpolation $dphi=$dtheta/$anz; for ($j = 0; $j <= $anz; $j++) { $tt=$dphi*$j; $cpi=cos($tt+$theta1); $spi=sin($tt+$theta1); # 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"; } ################################### # Markierung für x-Achse # marker for x-Axis $ppx=$rx; $ppy=0; $px=round($ca*$ppx-$sa*$ppy+$cx,$runden); $py=round($sa*$ppx+$ca*$ppy+$cy,$runden); } else { # Falls eine Hauptachse 0 ist, soll eine gerade Linie gezogen werden... # (if one major axis is 0, provide a straight line) $pfada="M$x1,$y1 L$x2,$y2"; # ansonsten undefinierter Krempel in der Ausgabe # (otherwise undefined stuff in output) ... $cx=0.5*($x1+$x2); $cy=0.5*($y1+$y2); $cxp=round($cx,$runden); $cyp=round($cy,$runden); $ppx=$rx; $ppy=0; $px=round($ca*$ppx-$sa*$ppy+$cx,$runden); $py=round($sa*$ppx+$ca*$ppy+$cy,$runden); } # viewBox berechnen / calculate viewBox $vv=max(4*ceil(0.6*max($rx,$ry)),400); $vh=1.5*$vv; $vy=round($cy-$vv/2); $vx=round($cx-$vh/2); $viewBox="$vx $vy $vh $vv"; # Text skalieren und formatieren: # (scale and format text) $fs=ceil($vv/25); $textx=$vx +10; $texty1=$vy +10+$fs; $texty2=$vy +10+2*$fs; $texty3=$vy +10+3*$fs; $break="\n"; $textpfad=wordwrap($pfada,55,$break, false); $textpfad="$textpfad"; # svg-header senden: $content="Content-type: image/svg+xml; charset=iso-8859-1"; header($content); # xml-Zeile ausgeben echo ""; # und jetzt das Dokument ?> SVG: Ellipsenbogen approximieren / Approximate an Elliptical Arc SVG Ellipsenbogen, der durch ein entsprechendes SVG-Kommando gegeben ist, mit einer kubischen Kurven nähern. Abschnitt einer Ellipse A, a: Anwendung zum Beispiel M x1, y1 A rx,ry phi fA, fS x2,y2 ... Parameter: x1, y1: Verschieben mit M - Anfangspunkt des Ellipsenbogens x2,y2: Endpunkt des Ellipsenbogens rx,ry : Radien der Ellipse phi: Drehung der großen Hauptachse ausgehend von der lokalen x-Achsen-Richtung fA: 1 größerer Teilbereich der Ellipse wird gemalt, 0 kleinerer fS: 1 gemalt wird in positiver Drehrichtung, 0 in negativer Mit dem GET-Parameter 'anz' kann die Anzahl der Interpolationspunkte angegeben werden, Voreinstellung ist 6. 'rnd' gibt an, auf wieviele Stellen gerundet wird, Voreinstellung ist 2 (Bereich 0 bis 4). Die anderen Parameter sind ebenfalls verfügbar: xi, yi, ri, phi/Grad im 'tiny'-Bereich -32767.9999 bis +32767.9999. SVG elliptical arc, given with the related SVG command is approximated with a cubic curve. Elliptical arc command A, a: use case for example M x1, y1 A rx,ry phi fA, fS x2,y2 ... Parameters: x1, y1: move to initial point of the elliptical arc x2,y2: endpoint of elliptical arc rx,ry : radii of the ellipse phi: rotation of the large main axis with respect to the x-axis fA: 1 large arc flag, 1 for larger part painted, 0 for smaller part fS: 1 sweep flag for painting direction, 1 positive, 0 negative With the GET parameter 'anz' the number of interpolation points can be given, default is 6. 'rnd' are the digits to be rounded in the fractional part of numbers in the output, default is 2 (range 0 to 4). The other parameters are available too, xi, yi, ri, phi/deg in the 'tiny' range -32767.9999 to +32767.9999. Komplette Ellipse / Complete Ellipse \n"; } echo " Originalpfad / Original Path \n"; if ($flag2) { echo " Approximierter Pfad / Approximated Path x-Hauptachsen-Markierung / x-major-axis marker Ellipsenzentrum / ellipse centre Anfangspunkt / initial point Endpunkt / final point Hauptachsen der Ellipse / major axes of the ellipse M x1,y1 A rx,ry phi fA,fS x2,y2 Pfadnotation / Path Notation $pfad Originalpfad / Original Path $textpfad Approximierter Pfad / Approximated Path\n"; } else { echo "M x1,y1 A rx,ry phi fA,fS x2,y2 Pfadnotation / Path Notation M/A: $pfad Originalpfad / Original Path Pfad nicht darzustellen / path to be omitted Approximierter Pfad / Approximated Path"; } ?>