以下是我的开源库中的三个函数。这些函数在 Java 中经过全面测试,但公式可以轻松翻译成任何语言。
签名是:
public static float getAngleFromPoint(final Point centerPoint, final Point touchPoint)
public static float getTwoFingerDistance(float firstTouchX, float firstTouchY, float secondTouchX, float secondTouchY)
Point getPointFromAngle(最终双角,最终双半径)
此解决方案假定像素密度是均匀分布的。
在旋转对象之前,请执行以下操作:
使用 getAngleFromPoint 计算从中心到右上角的角度(假设返回 20 度),即左上角为 -20 度或 340 度。
-
使用getTwoFingerDistance返回中心点到右上角的对角线距离(这个距离显然应该对所有角都相同,这个距离将在接下来的计算中使用)。
现在假设我们将对象顺时针旋转 30 度。我们现在知道右上角一定是50度,左上角是10度。
您现在应该可以在左上角和右上角使用 getPointFromAngle 函数了。使用从步骤 2 返回的半径。
从右上角乘以 2 的 X 位置应该得到新的宽度,从左上角乘以 2 的 Y 位置应该得到新的高度。
以上 4 个步骤应根据您旋转对象的程度来设置条件,否则您可以将高度作为宽度返回,将宽度作为高度返回。
请记住,角度函数以 0-1 而不是 0-360 的因数表示(在适当的情况下只需乘以或除以 360):
//从两点获取角度,表示为0 -1的因数(0表示0/360,0.25表示90度等)
public float getAngleFromPoint(final Point centerPoint, final Point touchPoint) {
float returnVal = 0;
//+0 - 0.5
if(touchPoint.x > centerPoint.x) {
returnVal = (float) (Math.atan2((touchPoint.x - centerPoint.x), (centerPoint.y - touchPoint.y)) * 0.5 / Math.PI);
}
//+0.5
else if(touchPoint.x < centerPoint.x) {
returnVal = (float) (1 - (Math.atan2((centerPoint.x - touchPoint.x), (centerPoint.y - touchPoint.y)) * 0.5 / Math.PI));
}//End if(touchPoint.x > centerPoint.x)
return returnVal;
}
//测量两点之间的对角线距离
public float getTwoFingerDistance(final float firstTouchX, final float firstTouchY, final float secondTouchX, final float secondTouchY) {
float pinchDistanceX = 0;
float pinchDistanceY = 0;
if(firstTouchX > secondTouchX) {
pinchDistanceX = Math.abs(secondTouchX - firstTouchX);
}
else if(firstTouchX < secondTouchX) {
pinchDistanceX = Math.abs(firstTouchX - secondTouchX);
}//End if(firstTouchX > secondTouchX)
if(firstTouchY > secondTouchY) {
pinchDistanceY = Math.abs(secondTouchY - firstTouchY);
}
else if(firstTouchY < secondTouchY) {
pinchDistanceY = Math.abs(firstTouchY - secondTouchY);
}//End if(firstTouchY > secondTouchY)
if(pinchDistanceX == 0 && pinchDistanceY == 0) {
return 0;
}
else {
pinchDistanceX = (pinchDistanceX * pinchDistanceX);
pinchDistanceY = (pinchDistanceY * pinchDistanceY);
return (float) Math.abs(Math.sqrt(pinchDistanceX + pinchDistanceY));
}//End if(pinchDistanceX == 0 && pinchDistanceY == 0)
}
//从给定半径的角度获取XY坐标(角度以0-1 0表示0/360度,0.75表示270等)
public Point getPointFromAngle(final double angle, final double radius) {
final Point coords = new Point();
coords.x = (int) (radius * Math.sin((angle) * 2 * Math.PI));
coords.y = (int) -(radius * Math.cos((angle) * 2 * Math.PI));
return coords;
}
这些代码 sn-ps 来自我的开源库:https://bitbucket.org/warwick/hgdialrepo 和 https://bitbucket.org/warwick/hacergestov2。
一个是安卓的手势库,另一个是安卓的拨号控件。还有一个拨盘控制的OpenGLES 2.0实现在:https://bitbucket.org/warwick/hggldial