400) ){ $thetadeg=mt_rand(1,400); } } else { $thetadeg=mt_rand(1,400); } $theta=$thetadeg*M_PI/180; $tmax=$thetadeg*$thetadeg+$thetadeg; # Anzahl der Interpolationspunkte eingeben: # (GET number of interpolation points) if(isset($_GET['anz'])) { $anz=$_GET['anz']; if (($anz < 2)OR($anz > 1000) ){ $anz=max(10,ceil($tmax/400)); } } else { $anz=max(10,ceil($tmax/400)); } $anzv=2*$anz; if(isset($_GET['ra'])) { $ra=$_GET['ra']; if (($ra < 0)OR($ra > 32767.9999) ){ $ra=mt_rand(100,1000); } } else { $ra=mt_rand(100,1000); } # runden auf wieviel Stellen / rounding to how many digits # Voreinstellung/ default $rnd=max(0,min(10,ceil(4-log10($ra)))); if(isset($_GET['rnd'])) { $runden=$_GET['rnd']; if (($runden < 0)OR($runden > 4) ){ $runden=$rnd; } } else { $runden=$rnd; } if(isset($_GET['cx'])) { $cx=$_GET['cx']; if (($cx < -32767.9999)OR($cx > 32767.9999) ){ $cx=mt_rand(-600,600); } } else { $cx=mt_rand(-600,600); } if(isset($_GET['cy'])) { $cy=$_GET['cy']; if (($cy < -32767.9999)OR($cy > 32767.9999) ){ $cy=mt_rand(-600,600); } } else { $cy=mt_rand(-600,600); } # Auswertung beginnen: # (start evaluation) # viewBox berechnen / calculate viewBox $rr=$ra; $rs=$ra; $vv=$ra*1.25; $vh=1.5*$vv; $vy=round($cy-$vv/100); $vx=round($cx-$vh/20); $viewBox="$vx $vy $vh $vv"; $sw=round($vv/100,$runden); $swr=$sw/4; ################################# # Vergleich, doppelte Punktzahl/ comparison, doubled number of points # Datensatz erzeugen / Interpolation $dphi=$theta/$anzv; $ianz=10; $ddphi=$dphi/$ianz; $xx=0; $yy=0; $ri=$ra*sqrt(M_PI); $pr=$ri/2; $data[0][0]=$xx+$cx; $data[0][1]=$yy+$cy; $data[0][2]=$ri*$dphi; $data[0][3]=0; for ($j = 1; $j <= $anzv; $j++) { $tt=$dphi*($j-1); $te=$dphi*$j; $randx=cos($tt*$tt*M_PI/2)+cos($te*$te*M_PI/2); $randy=sin($tt*$tt*M_PI/2)+sin($te*$te*M_PI/2); $sux=0; $suy=0; $sgx=0; $sgy=0; for ($i = 1; $i < $ianz; $i++) { $t=$tt+$ddphi*$i; $tu=$tt+(2*$i-1)*$ddphi/2; $cpig=cos($t*$t*M_PI/2); $spig=sin($t*$t*M_PI/2); $cpiu=cos($tu*$tu*M_PI/2); $spiu=sin($tu*$tu*M_PI/2); # Integral $sgx=$sgx + $cpig; $sgy=$sgy + $spig; $sux=$sux + $cpiu; $suy=$suy + $spiu; } $tu=$tt+(2*$ianz-1)*$ddphi/2; $cpiu=cos($tu*$tu*M_PI/2); $spiu=sin($tu*$tu*M_PI/2); $sux=$sux + $cpiu; $suy=$suy + $spiu; $xx=$xx+(4*$sux+2*$sgx+$randx)*$ri*$ddphi/6; $yy=$yy+(4*$suy+2*$sgy+$randy)*$ri*$ddphi/6; # Ableitungen / derivatives ... $dx=$ri*cos($te*$te*M_PI/2)*$dphi; $dy=$ri*sin($te*$te*M_PI/2)*$dphi; # Daten speichern / save data $data[$j][0]=$xx+$cx; $data[$j][1]=$yy+$cy; $data[$j][2]=$dx; $data[$j][3]=$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 <= $anzv; $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) $pfadv='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 <=$anzv; $j++) { $pfadv.=$cq[$j][0].' '.$cq[$j][1].' '.$data[$j][0].' '.$data[$j][1]."\n"; } ################################### # Datensatz erzeugen / Interpolation $dphi=$theta/$anz; $ianz=10; $ddphi=$dphi/$ianz; $xx=0; $yy=0; $ri=$ra*sqrt(M_PI); $pr=$ri/2; $data[0][0]=$xx+$cx; $data[0][1]=$yy+$cy; $data[0][2]=$ri*$dphi; $data[0][3]=0; for ($j = 1; $j <= $anz; $j++) { $tt=$dphi*($j-1); $te=$dphi*$j; $randx=cos($tt*$tt*M_PI/2)+cos($te*$te*M_PI/2); $randy=sin($tt*$tt*M_PI/2)+sin($te*$te*M_PI/2); $sux=0; $suy=0; $sgx=0; $sgy=0; for ($i = 1; $i < $ianz; $i++) { $t=$tt+$ddphi*$i; $tu=$tt+(2*$i-1)*$ddphi/2; $cpig=cos($t*$t*M_PI/2); $spig=sin($t*$t*M_PI/2); $cpiu=cos($tu*$tu*M_PI/2); $spiu=sin($tu*$tu*M_PI/2); # Integral $sgx=$sgx + $cpig; $sgy=$sgy + $spig; $sux=$sux + $cpiu; $suy=$suy + $spiu; } $tu=$tt+(2*$ianz-1)*$ddphi/2; $cpiu=cos($tu*$tu*M_PI/2); $spiu=sin($tu*$tu*M_PI/2); $sux=$sux + $cpiu; $suy=$suy + $spiu; $xx=$xx+(4*$sux+2*$sgx+$randx)*$ri*$ddphi/6; $yy=$yy+(4*$suy+2*$sgy+$randy)*$ri*$ddphi/6; # Ableitungen / derivatives ... $dx=$ri*cos($te*$te*M_PI/2)*$dphi; $dy=$ri*sin($te*$te*M_PI/2)*$dphi; # Daten speichern / save data $data[$j][0]=$xx+$cx; $data[$j][1]=$yy+$cy; $data[$j][2]=$dx; $data[$j][3]=$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"; $pl=' \n"; for ($j = 2; $j <=$anz; $j++) { $pfada.=$cq[$j][0].' '.$cq[$j][1].' '.$data[$j][0].' '.$data[$j][1]."\n"; $pl.='\n"; } ################################### $aus=" Pfadvergleich doppelte Punktanzahl / path comparsion, twice the number of points Approximierter Pfad / approximated path Punkte / points $pl "; $px=$pr+$cx; $py=$pr+$cy; $aus .=' Fixpunkt \n"; # Text skalieren und formatieren: # (scale and format text) $fs=round($vv/40,$runden); $lh=round(1.2*$vv/40,$runden); $textx=$vx +$fs; $texty=$vy +$lh; $texty2=$vy +2*$lh; $texty3=$vy +3*$lh; $break="\n"; $textpfad=wordwrap($pfada,100,$break, false); $textpfad="$textpfad"; $aus.=" ?cx=$cx&cy=$cy&ra=$ra&theta=$thetadeg&anz=$anz&rnd=$runden Aktuelle Werte / Current Values $textpfad Kubische Näherung / Cubic Approximation "; # svg-header senden: $content="Content-type: image/svg+xml; charset=iso-8859-1"; header($content); # xml-Zeile ausgeben echo ""; # und jetzt das Dokument ?> SVG: Pfadfragment für eine Klothoide oder Spinnlinie bestimmen / Determine a Klothoide path fragment Nach Angabe von GET-Parametern wird ein Spiralbogen als SVG-Kurve ermittelt und dargestellt, nicht angegebene Parameter werden zufällig gesetzt (Ausnahme anz und rnd). Um die Qualität der Näherung abzuschätzen, wird ein Vergleich mit einer Näherung mit doppelter Punktzahl durchgeführt, bei größeren Unterschieden ist die Anzahl der Punkte zu erhöhen. cx, cy: Startpunkt, Ursprung ra: Klothoiden-Parameter theta: > 0, Endwinkel von x-Achse aus anz: Anzahl der Stützstellen (ohne Angabe wird eine automatisch bestimmte angenommen). rnd: Anzahl der Rundungsstellen Due to given GET parameters a spiral arc is determined as SVG curve and painted, not specified parameters are choosen randomly (exception anz and rnd). To estimate the quality of the approximation, a comparison is given with another approximation with twice the number of points, with larger deviations the number of points needs to be enhanced. cx, cy: initial point, origin ra: Klothoiden parameter theta: > 0, final angle from x-axis anz: Number of curve points (if not specified, an automatically determined is choosen). rnd: the digits to be rounded in the fractional part of numbers in the output