2014-08-28 60 views
0

我正在iOS上開發一個2D應用程序,我需要做的是旋轉基於其中心的多邊形,並且還實現捕捉。現在我可以正確地旋轉它,但我不知道如何實現捕捉(當多邊形的任何一邊非常接近水平或垂直時,會自動使其水平或垂直)。這裏是我當前的代碼,我使用的是滑板使轉動這個多邊形基於其中心旋轉多邊形與捕捉

- (IBAction)sliderValueChanged:(UISlider *)sender { 

    // get rotateAngle 
    double rotateAngle = sender.value; 

    // if choosing any room, rotate it 
    if (choosedRoomAtIndex>0){ 

     // get the room 
     NSMutableArray *corners = rooms[choosedRoomAtIndex-1]; 

     // calculate center point 
     double centerX; 
     double centerY; 
     for (NSValue *pointValue in corners){ 
      CGPoint cornerPoint = [pointValue CGPointValue]; 
      centerX += cornerPoint.x; 
      centerY += cornerPoint.y; 
     } 
     CGPoint centerPoint = CGPointMake(centerX/corners.count, centerY/corners.count); 

     // calculate snap angle 
     **How To Calculate the angles that make any side horizontal or vertical?** 

     // rotate all the corner point based on the rotate angle 
     for (int j=0; j<corners.count; j++) { 

      // get current point 
      CGPoint cornerPoint = [corners[j] CGPointValue]; 

      // if very close to horizontal or vertical, snap it 
      if (fabs(rotateAngle-/*any snap angle*/)<rotateThreshold){ 
       rotateAngle = /*this snap angle*/; 
       NSLog(@"here"); 
      } 

      // perform the rotate 
      double s = sin(rotateAngle-lastRotatedAngle); 
      double c = cos(rotateAngle-lastRotatedAngle); 
      double newX = (cornerPoint.x-centerPoint.x)*c - (cornerPoint.y-centerPoint.y)*s + centerPoint.x; 
      double newY = (cornerPoint.x-centerPoint.x)*s + (cornerPoint.y-centerPoint.y)*c + centerPoint.y; 
      CGPoint movedPoint = CGPointMake(newX,newY); 
      [corners replaceObjectAtIndex:j withObject:[NSValue valueWithCGPoint:movedPoint]]; 

     } 
     [rooms replaceObjectAtIndex:choosedRoomAtIndex-1 withObject:corners]; 
     lastRotatedAngle = rotateAngle; 
     [self setNeedsDisplay]; 
    } 

} 

有沒有人可以幫我這個算法?任何職位將不勝感激。謝謝。

回答

0

我假設你的多邊形的邊緣在連續的角落之間運行(最後一個邊從最後一個角到第一個角)。如果是這樣的話,任何角落的角度由下式給出:

tan(角度)=((角落[i] + 1] .y-角落[i] .y)/(角落[i + 1 ] .x - corners [i] .x)

這裏角度是x軸下方的角度(順時針方向),所以爲了使它回到水平位置,你需要旋轉-angle。旋轉到垂直的角度(在上面的公式中交換x和y),並選擇兩個中較小的一個。如果兩個角已經水平或垂直對齊,則需要注意除以零(在這種情況下,不需要捕捉?)您可能需要注意「下一個」角落位於當前角落左側或上方的情況,儘管在實踐中我認爲這並不重要,因爲您可能想要選擇最小的快照角度。

我會遍歷所有角落,並找出每個的水平和垂直捕捉角度,然後使用所有這些角度中最小的角度。注意上面的公式是數學,而不是代碼 - 例如,您需要執行CGPointValue方法以從NSValues中提取。你需要用atan從上面的公式中獲得角度。