@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (topTouchArea.contains(event.getX(),event.getY())) { currentTouch = TOUCH_TOP; } else if (RightTouchArea.contains(event.getX(),event.getY())) { currentTouch = TOUCH_RIGHT; } else if (LeftTouchArea.contains(event.getX(),event.getY())) { currentTouch = TOUCH_LEFT; } else { return false; //Return false if user touches none of the corners } return true; case MotionEvent.ACTION_MOVE: switch (currentTouch) { case TOUCH_TOP: top.x = event.getX(); top.y = event.getY(); invalidate(); return true; case TOUCH_RIGHT: Right.x = event.getX(); Right.y = event.getY(); invalidate(); return true; case TOUCH_LEFT: Left.x = event.getX(); Left.y = event.getY(); invalidate(); return true; } case MotionEvent.ACTION_UP: switch (currentTouch) { case TOUCH_TOP: top.x = event.getX(); top.y = event.getY(); invalidate(); currentTouch = NONE; return true; case TOUCH_RIGHT: Right.x = event.getX(); Right.y = event.getY(); invalidate(); currentTouch = NONE; return true; case TOUCH_LEFT: Left.x = event.getX(); Left.y = event.getY(); invalidate(); currentTouch = NONE; return true; } return false; } return false; }
如何实现与CustomView的上述字符一起拖放….
解决方法
所以你有三个点A,B,C定义一个三角形.然后使用触摸点定义三条线以获得方向向量AT,BT,CT,而A,Cs表示这三条触摸线的基点.
然后用基点A定义边界线AB,用基点A定义AC(如果A或C是基点则无关紧要),最后用基点C定义CB线.所以总结(大字母是表示向量而小写字母表示标量或因子):
边界线:
a:X=A+f1*AB b:X=B+f2*BC c:X=C+f3*AC
触摸线:
ta:X=A+t1*AT tb:X=B+t2*BT tc:X=C+t3*CT
现在,您将触摸线(图中的粉红色)与触摸线基点相反的边界线(绿色/红色)相交.例如,您需要将线“ta”与线b相交以获得交点I3.如果您将向量AT扩展到因子t1,您将达到此点.
如果该因子t1大于1,则触摸点T位于A和I3之间,即“ta”线.如果因子t1小于1T,则位于线部分A-I3之外.
您必须使用行tb和c和tc以及a执行此操作三次.每次I(n)点需要小于1(其中n在{1,2,3}中).
如果此条件适用于所有三个交叉点,则您的触点位于三角形内.
您将通过解决这些简单的方程组来获得交点:
首先
A+t1*AT = B+f2*BC <=> 0 = A+t1*AT - B - f2*BC
这个系统看起来像这样(其中x,y捐赠特定的坐标组件):
0 = xA + t1*(xT-xA) - xB - f2*(xC-xB) 0 = yA + t1*(yT-yA) - yB - f2*(yC-yB)
第二
B+t2*BT = C+f3*AC <=> 0 = B+t2*BT - C - f3*AC
第三
C+t3*CT = A+f1*AB <=> 0 = C+t3*CT - A - f1*AB
如果某个点位于该区域内,解决这三个系统将为您提供答案.
解决方案需要与0明显不同(如果0是您的点在同一条线上的唯一解决方案 – >线性相关)!
基于此,您可以翻译对象的所有坐标.
如上所述,您需要减少三角形并将此方法应用于多边形的所有子三角形.如果符合条件(或者如果要实现多点触控则为两个或更多),则触摸位于对象区域内.
这只是三个小计算,应该在“Touch-Down”事件处理程序中调用一次.由于您知道您触摸了该区域,因此在移动手指时无需进行所有这些计算.
关于Trianglization
这是一个更复杂的问题,一句话没有回答.根据你对另一个答案的评论,你不想处理简单的多边形,你想要处理由多边形组成的更复杂的形状.例如你的星形.在这里你可以使用上面的方法,你需要自己定义三角形.因为知道哪个角落属于一个面而不是哪个角落并不那么简单.
另一种解决方案是使用所谓的Quick Hull算法从点集生成凸包.这将为您提供形状的轮廓,您应该使用三角形的角点.如果您有一些“无阴影”的面孔,只需触摸它们,如果您真的想要处理所有可能的点集.
我的解决方案明星案例:
>定义尖峰三角形
>使用我前面提到的方法(通过解决一些LSE)来确定是否触摸了一个.
其他一切:
通过使用三角形的外接圆来三角化它.通过找到定义不包含任何其他轮廓点的圆的三个点.所谓的Delaunay Triangulation.
让这个方法找到你的三角形.如果你有一些没有阴影的区域,你可以用属性“touchable”或类似的东西来定义一个三角形对象,让你的算法知道是否应该处理触摸.
如果您正确处理和更新三角形组,则不应再有关于如何处理凹形的问题.
对于你的五角大楼尝试以下: