矩形区域会判断吧(网上可以查到不同方式,选自己习惯的),拿图1为例: if (x < 0 || x > w / 2 || y < 0 || y > h / 2) {//排除矩形外的区域 return false; } return true; 这样图1的矩形区域就出来了吧,但是实际还要去掉三角形的区域,那么反向来想,就是那条斜线以上的区域,因为把矩形的区域已经筛选出来了。实际上就是矩形和斜线以上的交集。 那么斜线以上的区域怎么获得,下面是直线的公式其中P1(w / 4, h / 2),P2(w / 2, h / 4) 带入公式后最后得到:x + (w / h) * y - (3 / 4) * w = 0;斜线以上的区域就是x + (w / h) * y - (3 / 4) * w < 0; 所以图1的最后点击区域是: private boolean isTopLeft(MotionEvent event) { float w = getWidth(); float h = getHeight(); float x = event.getX(); float y = event.getY(); if (x < 0 || x > w / 2 || y < 0 || y > h / 2) { return false; } if ((w / h) * y + x - 3 * w / 4 < 0) { return true; } return false; } 同理,其他3个梯形的点击区域就按部就班,这个不用说了吧。 最后剩一个菱形,这个怎么办?不是每个梯形判断的时候都有条直线吗,那条直线的反向区域的交集就是这个菱形的点击区域,即x + (w / h) * y - (3 / 4) * w < 0变为x + (w / h) * y - (3 / 4) * w > 0然后和另外三条直线逻辑与(&&)操作就可以了。多再本子上画画,光靠想脑子有时候不够用。
//x<w/4 || x>3w/4 || y<h/4 || y>3h/4 if(x < w/4 && y < h/2) case 1; else if(x > 3w/4 && y < h/2) case 2; else if(x < w/4 && y >= h/2) case 3; else if(x > 3e/4 && y >= h/2) case 4;//else else if(x < w/2 && y < h/2) (h/2-y > x-w/4) ? (case 1) : (case 5); else ...其实呢,网上也有通过向量叉乘判断点在图形内或者点在图形外的,但是理解比较困难;还有就是如果你把菱形换成圆形就很简单了
抱歉,楼上哥们是对的,我斜率都当成1了,修改下也没太大问题。 提供个根据坐标判断点在多边形外还是多边形内的方法(是在标准坐标系下的,和手机屏幕坐标系也许会有差异,自己调试下罗)//MyPoint是我自己定义的点结构类,其实也就一个x一个y /** * 判断平面上,点是否在指定多边形内 * * @param point * @param points * @return */ public static boolean InsidePolygon(MyPoint point, MyPoint[] points) { int i = 0, sum = 0; int n = points.length; MyPoint t = new MyPoint(point.x, point.y); MyPoint[] p = new MyPoint[n + 1]; for (i = 0; i < n; i++) { // 坐标平移 p[i] = new MyPoint(points[i].x - t.x, points[i].y - t.y); } p[n] = new MyPoint(p[0].x, p[0].y); int flag1 = p[0].x >= 0 ? (p[0].y >= 0 ? 0 : 3) : (p[0].y >= 0 ? 1 : 2); // 计算象限 for (sum = 0, i = 1; i <= n; i++) { if (p[i].x == 0 && p[i].y == 0) // 被测点为多边形顶点 break; double f = p[i].y * p[i - 1].x - p[i].x * p[i - 1].y; // 计算叉积 if (f == 0 && p[i - 1].x * p[i].x <= 0 && p[i - 1].y * p[i].y <= 0) // 点在边上 break; int flag2 = p[i].x >= 0 ? (p[i].y >= 0 ? 0 : 3) : (p[i].y >= 0 ? 1 : 2); // 计算象限 if (flag2 == (flag1 + 1) % 4) // 下一象限 sum += 1; else if (flag2 == (flag1 + 3) % 4) // 上一象限 sum -= 1; else if (flag2 == (flag1 + 2) % 4) // 同一象限 { if (f > 0) sum += 2; else sum -= 2; } flag1 = flag2; } if (i <= n || sum != 0) return true; return false; }
private boolean isInsideTopLeft(MotionEvent event) {
float x = event.getX();
float y = event.getY();
float w = getWidth();
float h = getHeight();
return y < (-2*x + 3*w/2) && y < (x/2 + w/4);
}
如
if(x < 0 || x > w / 2 || y < 0 || y > h / 2){
return false;
}
这个是左上的那个,然后判断下与斜线的交集,具体网上也能查到直线相关的东西。
这样4个五边形就搞定了,中心的菱形就判断下四条直线的交集(最笨的方法)其实就是判断坐标轴上的区域
如果你能把布局弄成图画的样子,那么点击区域根本不是问题,ImageView自己会处理点击事件。抛开上面的,光看楼主画的5个图,简单的判断:
1 2 3 4 分割整体成4部分, 5切分成上下两个三角形。-》》》down 判断在 1 2 3 4哪个矩形中,(Rect类有提供点是否在内部的函数C开头的,名字不记得)。-》》》假设在1 或者2矩形,判断是否在 5的上三角形内部。判断点是否在三角形内部,请自行google或者参考这个。
如果在 5的上三角形内部,则点击区域为5,否则点击区域为1或者2.3 4区域 依样画葫芦即可。
if (x < 0 || x > w / 2 || y < 0 || y > h / 2) {//排除矩形外的区域
return false;
}
return true;
这样图1的矩形区域就出来了吧,但是实际还要去掉三角形的区域,那么反向来想,就是那条斜线以上的区域,因为把矩形的区域已经筛选出来了。实际上就是矩形和斜线以上的交集。
那么斜线以上的区域怎么获得,下面是直线的公式其中P1(w / 4, h / 2),P2(w / 2, h / 4)
带入公式后最后得到:x + (w / h) * y - (3 / 4) * w = 0;斜线以上的区域就是x + (w / h) * y - (3 / 4) * w < 0;
所以图1的最后点击区域是: private boolean isTopLeft(MotionEvent event) {
float w = getWidth();
float h = getHeight();
float x = event.getX();
float y = event.getY();
if (x < 0 || x > w / 2 || y < 0 || y > h / 2) {
return false;
}
if ((w / h) * y + x - 3 * w / 4 < 0) {
return true;
}
return false;
}
同理,其他3个梯形的点击区域就按部就班,这个不用说了吧。
最后剩一个菱形,这个怎么办?不是每个梯形判断的时候都有条直线吗,那条直线的反向区域的交集就是这个菱形的点击区域,即x + (w / h) * y - (3 / 4) * w < 0变为x + (w / h) * y - (3 / 4) * w > 0然后和另外三条直线逻辑与(&&)操作就可以了。多再本子上画画,光靠想脑子有时候不够用。
if(x < w/4 && y < h/2) case 1;
else if(x > 3w/4 && y < h/2) case 2;
else if(x < w/4 && y >= h/2) case 3;
else if(x > 3e/4 && y >= h/2) case 4;//else
else if(x < w/2 && y < h/2) (h/2-y > x-w/4) ? (case 1) : (case 5);
else ...其实呢,网上也有通过向量叉乘判断点在图形内或者点在图形外的,但是理解比较困难;还有就是如果你把菱形换成圆形就很简单了
提供个根据坐标判断点在多边形外还是多边形内的方法(是在标准坐标系下的,和手机屏幕坐标系也许会有差异,自己调试下罗)//MyPoint是我自己定义的点结构类,其实也就一个x一个y
/**
* 判断平面上,点是否在指定多边形内
*
* @param point
* @param points
* @return
*/
public static boolean InsidePolygon(MyPoint point, MyPoint[] points) {
int i = 0, sum = 0;
int n = points.length;
MyPoint t = new MyPoint(point.x, point.y);
MyPoint[] p = new MyPoint[n + 1];
for (i = 0; i < n; i++) { // 坐标平移
p[i] = new MyPoint(points[i].x - t.x, points[i].y - t.y);
}
p[n] = new MyPoint(p[0].x, p[0].y); int flag1 = p[0].x >= 0 ? (p[0].y >= 0 ? 0 : 3) : (p[0].y >= 0 ? 1 : 2); // 计算象限 for (sum = 0, i = 1; i <= n; i++) {
if (p[i].x == 0 && p[i].y == 0) // 被测点为多边形顶点
break;
double f = p[i].y * p[i - 1].x - p[i].x * p[i - 1].y; // 计算叉积
if (f == 0 && p[i - 1].x * p[i].x <= 0 && p[i - 1].y * p[i].y <= 0) // 点在边上
break;
int flag2 = p[i].x >= 0 ? (p[i].y >= 0 ? 0 : 3) : (p[i].y >= 0 ? 1
: 2); // 计算象限
if (flag2 == (flag1 + 1) % 4) // 下一象限
sum += 1;
else if (flag2 == (flag1 + 3) % 4) // 上一象限
sum -= 1;
else if (flag2 == (flag1 + 2) % 4) // 同一象限
{
if (f > 0)
sum += 2;
else
sum -= 2;
}
flag1 = flag2;
} if (i <= n || sum != 0)
return true;
return false;
}