4) ){ $runden=2; } } else { $runden=2; } # Parameter ... if(isset($_GET['theta'])) { $thetadeg=$_GET['theta']; if (($thetadeg < 0)OR($thetadeg > 32767.9999) ){ $thetadeg=mt_rand(1,10000); } } else { $thetadeg=mt_rand(1,10000); } $theta=$thetadeg*M_PI/180; if(isset($_GET['phi0'])) { $phideg=$_GET['phi0']; if (($phideg <0)OR($phideg > 32767.9999) ){ $phideg=mt_rand(1,1000); } } else { $phideg=mt_rand(1,1000); } $phi=$phideg*M_PI/180; # Anzahl der Interpolationspunkte eingeben: # (GET number of interpolation points) if(isset($_GET['anz'])) { $anz=$_GET['anz']; if (($anz < 2)OR($anz > 1000) ){ $anz=max(3,ceil(abs($thetadeg)/30)); } } else { $anz=max(3,ceil(abs($thetadeg)/30)); } $anzv=2*$anz; if(isset($_GET['ra'])) { $radeg=$_GET['ra']; if (($radeg < -32767.9999)OR($radeg > 32767.9999) ){ $radeg=mt_rand(-1000,1000); } } else { $radeg=mt_rand(-1000,1000); } $ra=$radeg*M_PI/180; 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/($theta+$phi); $rs=$ra/$phi; $rs=max(abs($rr),abs($rs)); $vv=4*ceil(0.4*$rs); $vh=1.5*$vv; $vy=round($cy-$vv/1.85); $vx=round($cx-$vh/2); $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; for ($j = 0; $j <= $anzv; $j++) { $tt=$dphi*$j+$phi; $cpi=cos($tt); $spi=sin($tt); $ri=$ra/$tt; $dr=-$ra/$tt/$tt; # Punkte / points $xx=$ri*$cpi; $yy=$ri*$spi; # Ableitungen / derivatives ... $dx=$dr*$dphi*$cpi -$dphi*$ri*$spi; $dy=$dr*$dphi*$spi +$dphi*$ri*$cpi; # 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; for ($j = 0; $j <= $anz; $j++) { $tt=$dphi*$j+$phi; $cpi=cos($tt); $spi=sin($tt); $ri=$ra/$tt; $dr=-$ra/$tt/$tt; # Punkte / points $xx=$ri*$cpi; $yy=$ri*$spi; # Ableitungen / derivatives ... $dx=$dr*$dphi*$cpi -$dphi*$ri*$spi; $dy=$dr*$dphi*$spi +$dphi*$ri*$cpi; # 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) for ($j = 0; $j <= $anz; $j++) { $cp[$j][0]=round($data[$j][0]+$data[$j][2]/3,$runden); $cp[$j][1]=round($data[$j][1]+$data[$j][3]/3,$runden); $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); } # Fehler abschätzen / estimate error $fehl=0; $fmax=0; $fanz=0; for ($j = 0; $j <= $anz; $j++) { $jj=$j+1; if ($j != $anz) { for ($i = 0; $i < 30; $i++) { $tf=$dphi*($j+$i/30)+$phi; $cpi=cos($tf); $spi=sin($tf); $ri=$ra/$tf; # Punkte / points $xx=$ri*$cpi+$cx; $yy=$ri*$spi+$cy; $u=$i/30; $ur=(1-$u); $x1=$ur*$ur*$ur*$data[$j][0]+3*$u*$ur*$ur*$cp[$j][0] +3*$u*$u*$ur*$cq[$jj][0]+ $u*$u*$u*$data[$jj][0]; $y1=$ur*$ur*$ur*$data[$j][1]+ 3*$u*$ur*$ur*$cp[$j][1] + 3*$u*$u*$ur*$cq[$jj][1]+ $u*$u*$u*$data[$jj][1]; $dxx=$x1-$xx; $dyy=$y1-$yy; $fdd=sqrt($dxx*$dxx+$dyy*$dyy); $fehl=$fehl+$fdd; if ($fdd > $fmax) { $fmax=$fdd; $fx=$xx; $fy=$yy; } $fanz=$fanz+1; } } } $fehl=$fehl/$fanz; # 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=" Zentrum / centre maximaler Fehler / maximal error Pfadvergleich doppelte Punktanzahl / path comparsion, twice the number of points Approximierter Pfad / approximated path Punkte / points $pl "; # 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; $texty1=$vy +2*$lh; $texty2=$vy +3*$lh; $texty3=$vy +4*$lh; $break="\n"; $textpfad=wordwrap($pfada,100,$break, false); $textpfad="$textpfad"; $aus.=" ?cx=$cx&cy=$cy&ra=$radeg&theta=$thetadeg&phi0=$phideg&anz=$anz&rnd=$runden Aktuelle Werte / Current Values $fmax | $fehl Fehler maximal, mittel / Error maximum, average $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 hyperbolische Spirale bestimmen / Determine a hyperbolic spiral 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: Zentrum der Spirale ra: Radius r = ra/phi (ra in Grad) phi0: Anfangswinkel > 0 theta: > 0, Endwinkel phi0 + theta von x-Achse aus anz: Anzahl der Stützstellen (ohne Angabe wird eine Winkeldifferenz von maximal 30 Grad angenommen und daraus wird dann anz automatisch bestimmt). 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: center of the spiral ra: Radius r = ra/phi (ra in degree) phi0: initial angle > 0 theta: > 0, final angle phi0 + theta from x-axis anz: Number of curve points (if not specified, the angle difference not larger than 30 degree is choosen and anz is determined automatically). rnd: the digits to be rounded in the fractional part of numbers in the output