duancong7573 2014-01-19 04:54
浏览 36
已采纳

围绕点旋转多边形

Several web sites give the same answer, but it's not working for me. I'd appreciate any guidance in where I'm going wrong.

Situation: I want to rotate a polygon. I have the coordinates of each point. I run each point through this function, which should give me the rotated polygon. However, the new one is shorter and wider than the original - it changes shape. Here is a more complete version of my code;

function rotatePoint($coord,$rot){
/*
in - x, y coordinate, how much to rotate in degrees
do - rotate each point
out - end coordinate point

rotate a point (x, y) by t radians counterclockwise
about the origin (0, 0), the transformed coordinates (x', y')
can be computed by:

x' = cos(t)*x - sin(t)*y
y' = sin(t)*x + cos(t)*y
*/
    $rotRad=deg2rad($rot);
    $rotCoord=array();
    $rotCoord['x']=(cos($rotRad)*$coord['x'])-(sin($rotRad)*$coord['y']);
    $rotCoord['y']=(sin($rotRad)*$coord['x'])+(cos($rotRad)*$coord['y']);
    return $rotCoord;
};

$polygonPoints=array(
array('y'=>40.039363507917,'x'=>-76.112888306379),
array('y'=>40.039369668435,'x'=>-76.112935245037),
array('y'=>40.039246457955,'x'=>-76.112959384918),
array('y'=>40.039240297425,'x'=>-76.11291244626),
array('y'=>40.039363507917,'x'=>-76.112888306379)
           );
         $rotateAmt=90;//how much to rotate

          $pointX = array();
          $pointY = array();
          foreach ($polygonPoints as $key => $row)
          {
            $pointX[$key] = $row['x'];
            $pointY[$key] = $row['y'];
          }
          $maxX=$minX=$polygonPoints[0]['x'];
          $maxY=$minY=$polygonPoints[0]['y'];
          for($i=0;$i<count($polygonPoints);$i++){
            if($polygonPoints[$i]['x']>=$maxX){$maxX=$polygonPoints[$i]['x'];};
            if($polygonPoints[$i]['x']<$minX){$minX=$polygonPoints[$i]['x'];};
            if($polygonPoints[$i]['y']>=$maxY){$maxY=$polygonPoints[$i]['y'];};
            if($polygonPoints[$i]['y']<$minY){$minY=$polygonPoints[$i]['y'];};
          }
          $center=array('x'=>($maxX+$minX)/2,'y'=>($maxY+$minY)/2);
    $adjustment=array('x'=>0-$center['x'],'y'=>0-$center['y']);
    echo 'Adjustment<pre>';
    var_dump($adjustment);
    echo'</pre>';
    $adjustedPolygon=array();
    for($i=0;$i<count($polygonPoints);$i++){
    $adjustedPolygon[$i]['x']=$polygonPoints[$i]['x']+$adjustment['x'];
    $adjustedPolygon[$i]['y']=$polygonPoints[$i]['y']+$adjustment['y'];

          }

$rotatedPolygon=array();
      for($i=0;$i<count($adjustedPolygon);$i++){
     //     echo 'before rotatePoint '.$i.'='.$adjustedPolygon[$i]['x'].', '.$adjustedPolygon[$i]['y'].'<br />';
          $rotatedPolygon[$i]=rotatePoint($adjustedPolygon[$i],$rotateAmt);
     //     echo 'after rotatePoint '.$i.'='.$rotatedPolygon[$i]['x'].', '.$rotatedPolygon[$i]['y'].'<br />';
          $rotatedPolygon[$i]['x']=$rotatedPolygon[$i]['x']-$adjustment['x'];
          $rotatedPolygon[$i]['y']=$rotatedPolygon[$i]['y']-$adjustment['y'];
      }

Thanks for the help. Let me know if I should put this on math.stackexchange.com

  • 写回答

1条回答 默认 最新

  • dousao6260 2015-03-30 17:39
    关注

    This is the solution I came up with...

    It takes a whole array of points and rotates around a specified centre. It also scales the polygon if required. The function returns a new one-dimensional array of points.

    The array is one dimensional as I wrote this to use in the PHP imagepolygon() function.

    ################################################################### 
    #####               ROTATE POLYGON FUNCTION                   #####
    #####                                                         #####
    #####               PLEASE DO REMOVE THIS NOTICE              #####
    #####               by Steve Burgess - 2015                   #####
    ###################################################################
    # $polygon - points of the polygon in a 1 dimensional array
    #            e.g. (x1,y1,x2,y2,x3,y3.... etc)
    # $angle   - rotation angle in degrees
    # $centrex - x coordinate of centre of rotation
    # $centrey - y coordinate of centre of rotation
    # $scale   - scale for resizing the polygon
    #
    # The function returns a new array of scaled/rotated values that can
    # be used in the imagepolygon() and imagefilledpolygon() functions
    ###################################################################
    
    function rotatepolygon($polygon,$angle=0,$centrex,$centrey,$scale=1)
    {
    # I have negated the angle here so the function rotates in the same
    # direction as the imagerotate() function in PHP
    
    # PHP Trigonometric Functions (e.g. cosine, sine) require the angle to
    # be in radians rather than degrees - hence the deg2rad() conversion.
    
    $angle=deg2rad(-$angle); 
    
    if($scale<>1)
    {
        # Using the array_map() function performs the scaling for the entire array
        # in one line - rather than having to write code that loops through the array.       
    
    $polygonscaled = array_map("scale",$polygon,array_fill(0,count($polygon),$scale));
        $polygon=$polygonscaled;
        $centrex=$centrex*$scale;
        $centrey=$centrey*$scale;
    }
    
    for($i=0;$i<count($polygon);$i=$i+2)
    {
        # Using the array map function to perform these transformations was beyond me.
        # If anyone has any bright ideas about this, please drop me a line
    
        # Original coordinates of each point
    $x=$polygon[$i];$y=$polygon[$i+1];
    
        # As imagepolygon requires a 1 dimensional array, the new x and the new y
        # coordinates are simply added to the rotated array one after the other
        $rotated[]=($centrex+(($x-$centrex)*cos($angle))-(($y-$centrey)*sin($angle))); 
    $rotated[]=($centrey+(($x-$centrex)*sin($angle))+(($y-$centrey)*cos($angle))); 
    }
    
    return $rotated;
    }
    
    function scale($value,$scale)
    {
    # This function is essential for the polygon rotate function.
    # Make sure you copy/paste this into your code as well as the main function.
    
    return($value*$scale);
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记