2011-08-28 41 views
0

我有一組X,Y點並希望在PHP內插紅衣主教曲線之間,一組高詳細點的PHP插補點

我不能讓我圍繞如何頭將網絡上的數學公式轉換爲PHP函數或類

任何人都可以幫忙嗎?

回答

3

下面是我想出來的情況下,任何其他人也面臨同樣的問題

function caculate_cardinal_points($points,$tension=0.5,$steps=20) { 

    $return_points = array(); 
    $tangents = array(); 

    // calculate tangents 
    $previous_point = false; 
    for($i=0;$i<count($points);$i++) { 
     $px = $points[$i][0]; 
     $py = $points[$i][1]; 
     if (isset($points[$i+1]) && isset($points[$i-1])) { 
      $tx = ($tension * (($points[$i+1][0]-$px) - ($points[$i-1][0]-$px))); 
      $ty = ($tension * (($points[$i+1][1]-$py) - ($points[$i-1][1]-$py))); 
     } elseif (isset($points[$i+1])) { 
      $tx = ($tension * (($points[$i+1][0]-$px) - ($points[$i][0]-$px))); 
      $ty = ($tension * (($points[$i+1][1]-$py) - ($points[$i][1]-$py))); 
     } elseif (isset($points[$i-1])) { 
      $tx = ($tension * (($points[$i][0]-$px) - ($points[$i-1][0]-$px))); 
      $ty = ($tension * (($points[$i][1]-$py) - ($points[$i-1][1]-$py))); 
     } 
     $tangents[] = array($tx,$ty); 
     $previous_x = $px; 
     $previous_y = $py; 
    } 

    // interpolate 
    for($i=0;$i<count($tangents)-1;$i++) { 
     $p0x = $points[$i][0]; 
     $p0y = $points[$i][1]; 
     $p1x = $points[$i+1][0]; 
     $p1y = $points[$i+1][1]; 
     $t0x = $tangents[$i][0]; 
     $t0y = $tangents[$i][1]; 
     $t1x = $tangents[$i+1][0]; 
     $t1y = $tangents[$i+1][1]; 
     $previous_x = $p0x; 
     $previous_y = $p0y; 
     $return_points[] = array($p0x,$p0y); 
     for ($t=0; $t < $steps; $t++) { 
      $s = $t/$steps; // scale s to go from 0 to 1 
      $h1 = 2*pow($s,3) - 3*pow($s,2) + 1; 
      $h2 = pow($s,3) - 2*pow($s,2) + $s; 
      $h3 = -2*pow($s,3) + 3*pow($s,2); 
      $h4 = pow($s,3) - pow($s,2); 
      $x = $h1*$p0x+$h2*$t0x+$h3*$p1x+$h4*$t1x; 
      $y = $h1*$p0y+$h2*$t0y+$h3*$p1y+$h4*$t1y; 
      $return_points[] = array($x,$y); 
      $previous_x = $x; 
      $previous_y = $y; 
     } 
     $return_points[] = array($p1x,$p1y); 
    } 
    return $return_points; 
} 

在這裏,在使用它的例子的解決方案:

<?php 

$width = 600; 
$height = 600; 
$factor = 1; 
$steps = 20; 
$tension = .25; 

$blue = 0x00257ac7; 
$green = 0x0096be44; 
$black = 0x009999999; 
$purple = 0x00b5499a; 
$red = 0x00ff5555; 
$bgreen = 0x0000ff00; 

$img = imagecreatetruecolor($width*$factor, $height*$factor); 

// background fill 
imagefill($img, 0, 0, 0x00dddddd); 

// some control points 
$points = array(
    array(120 *$factor,140 *$factor), 
    array(140 *$factor,350*$factor), 
    array(180 *$factor,500*$factor), 
    array(430*$factor,350*$factor), 
    array(390*$factor,210*$factor), 
    array(540*$factor,120 *$factor) 
); 
$last_point = false; 
foreach($points as $point) { 
    imagefilledellipse($img,$point[0],$point[1],8*$factor,8*$factor,$blue); 
    if ($last_point) { 
     imageline($img,$point[0],$point[1],$last_point[0],$last_point[1],$purple); 
    } 
    $last_point = $point; 
} 


$tangets = array(); 

// calculate tangents 
$previous_point = false; 
for($i=0;$i<count($points);$i++) { 
    $px = $points[$i][0]; 
    $py = $points[$i][1]; 
    if (isset($points[$i+1]) && isset($points[$i-1])) { 
     $tx = ($tension * (($points[$i+1][0]-$px) - ($points[$i-1][0]-$px))); 
     $ty = ($tension * (($points[$i+1][1]-$py) - ($points[$i-1][1]-$py))); 
    } elseif (isset($points[$i+1])) { 
     $tx = ($tension * (($points[$i+1][0]-$px) - ($points[$i][0]-$px))); 
     $ty = ($tension * (($points[$i+1][1]-$py) - ($points[$i][1]-$py))); 
    } elseif (isset($points[$i-1])) { 
     $tx = ($tension * (($points[$i][0]-$px) - ($points[$i-1][0]-$px))); 
     $ty = ($tension * (($points[$i][1]-$py) - ($points[$i-1][1]-$py))); 
    } 
    $tangets[] = array($tx,$ty); 
    imageline($img,$px+$tx,$py+$ty,$points[$i][0],$points[$i][1],$black); 
    imagefilledellipse($img,$px+$tx,$py+$ty,4*$factor,4*$factor,$green); 
    imageline($img,$px-$tx,$py-$ty,$points[$i][0],$points[$i][1],$black); 
    imagefilledellipse($img,$px-$tx,$py-$ty,4*$factor,4*$factor,$green); 
    $previous_x = $px; 
    $previous_y = $py; 
} 


for($i=0;$i<count($tangets)-1;$i++) { 
    $p0x = $points[$i][0]; 
    $p0y = $points[$i][1]; 
    $p1x = $points[$i+1][0]; 
    $p1y = $points[$i+1][1]; 
    $t0x = $tangets[$i][0]; 
    $t0y = $tangets[$i][1]; 
    $t1x = $tangets[$i+1][0]; 
    $t1y = $tangets[$i+1][1]; 
    $previous_x = $p0x; 
    $previous_y = $p0y; 
    for ($t=0; $t < $steps; $t++) { 
     $s = $t/$steps; // scale s to go from 0 to 1 
     $h1 = 2*pow($s,3) - 3*pow($s,2) + 1; 
     $h2 = pow($s,3) - 2*pow($s,2) + $s; 
     $h3 = -2*pow($s,3) + 3*pow($s,2); 
     $h4 = pow($s,3) - pow($s,2); 
     $x = $h1*$p0x+$h2*$t0x+$h3*$p1x+$h4*$t1x; 
     $y = $h1*$p0y+$h2*$t0y+$h3*$p1y+$h4*$t1y; 
     //imageline($img,$previous_x,$previous_y,$x,$y,$red); 
     $previous_x = $x; 
     $previous_y = $y; 
    } 
    //imageline($img,$previous_x,$previous_y,$p1x,$p1y,$red); 
} 

$line_points = caculate_cardinal_points($points); 
$previous_point = false; 
foreach($line_points as $point) { 
    if ($previous_point) { 
     imageline($img,$previous_point[0],$previous_point[1],$point[0],$point[1],$red); 
    } 
    $previous_point = $point; 
} 


$resampled = imagecreatetruecolor($width, $height); 
imagecopyresampled($resampled,$img,0,0,0,0,$width,$height,$width*$factor,$height*$factor); 
header("Content-Type: image/png"); 
imagepng($resampled); 
imagedestroy($img); 
imagedestroy($resampled);