我在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 :(得分:0)
我假设多边形的边缘在连续的角落之间运行(最后一个边缘从最后一个角落到第一个边缘)。如果是这种情况,则任何角落到下一个角的角度由
给出tan(角度)=((corner [i + 1] .y - corner [i] .y)/(corner [i + 1] .x - corner [i] .x)
此处角度是x轴下方的角度(顺时针方向)。因此,要将其捕捉回水平,您需要按角度旋转。我还要计算旋转到垂直的角度(在上面的等式中交换x和y),然后选择两者中较小的一个。如果两个角已经水平或垂直对齐(在这种情况下,不需要捕捉?),您需要注意除以零。您可能需要注意&#34; next&#34;角落在当前角落的左侧或上方,虽然在实践中我认为这无关紧要,因为您可能想要选择最小的角度。
我会遍历所有角落并找到每个角落的水平和垂直捕捉角度,然后使用所有这些角度中最小的角度。请注意,上面的公式是数学,而不是代码 - 例如,您需要使用CGPointValue方法从NSValues中提取。你需要使用atan来获得上述公式的角度。