Android 如何绑定点集(自定义形状)并在其上触摸事件

Android 如何绑定点集(自定义形状)并在其上触摸事件,android,canvas,bitmap,Android,Canvas,Bitmap,我可以使用 现在我的问题是如何将这些点绑定为形状/区域。意思是当用户触摸到我的边界点的区域时,我想根据这个移动对象(形状)。上面链接彩色位图的返回点(它删除透明部分),只有彩色部分点作为数组返回。 这就是我的代码: 1) CustomSahpe.java public class CustomShape { private final Context context; Bitmap bitmap; int width, height; int[] pixels; private final A

我可以使用 现在我的问题是如何将这些点绑定为形状/区域。意思是当用户触摸到我的边界点的区域时,我想根据这个移动对象(形状)。上面链接彩色位图的返回点(它删除透明部分),只有彩色部分点作为数组返回。 这就是我的代码:

1) CustomSahpe.java

public class CustomShape {
private final Context context;

Bitmap bitmap;
int width, height;
int[] pixels;
private final ArrayList<Point> points = new ArrayList<Point>();
public CustomShape(Context context) {
    // TODO Auto-generated constructor stub
    // super(context);
    this.context = context;
    bitmap = BitmapFactory.decodeResource(context.getResources(),
            R.drawable.ic_menu_balloon);
    width = bitmap.getWidth();
    height = bitmap.getHeight();
    pixels = new int[width * height];
    bitmap.getPixels(pixels, 0, width, 0, 0, width, height);        
    getActualBitmap();
}

public ArrayList<Point> getPoints(){
    return points;
}

public void getActualBitmap() {
    for (int x = 0; x < width; x+=2) {
        int firstY = -1, lastY = -1;
        for (int y = 0; y < height; y+=2) {
            boolean transparent = (pixels[y * width + x] == Color.TRANSPARENT);
            if (!transparent) {
                if (firstY == -1) {
                    firstY = y;
                }
                lastY = y;
            }
        }
        if (firstY != -1) {
            points.add(new Point(x, firstY));
            points.add(new Point(x, lastY));
        }
    }
}
4) ScaleTestActivity.java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);      
    setContentView(new MainPanel(this));
}

我使用多边形类来检测旋转位图上的接触。它主要基于这个网站的信息和代码。这应该适用于您的代码

public class Polygon {

// Polygon coodinates.
private final int[] polyY, polyX;

// Number of sides in the polygon.
private final int polySides;

/**
 * Default constructor.
 * @param px Polygon y coods.
 * @param py Polygon x coods.
 * @param ps Polygon sides count.
 */
public Polygon( final int[] px, final int[] py, final int ps ) {
    polyX = px;
    polyY = py;
    polySides = ps;
}

/**
 * Checks if the Polygon contains a point.
 * @see "http://alienryderflex.com/polygon/"
 * @param x Point horizontal pos.
 * @param y Point vertical pos.
 * @return Point is in Poly flag.
 */
public boolean contains( final float x, final float y ) {

    boolean oddTransitions = false;
    for( int i = 0, j = polySides -1; i < polySides; j = i++ ) {
        if( ( polyY[ i ] < y && polyY[ j ] >= y ) || ( polyY[ j ] < y && polyY[ i ] >= y ) ) {
            if( polyX[ i ] + ( y - polyY[ i ] ) / ( polyY[ j ] - polyY[ i ] ) * ( polyX[ j ] - polyX[ i ] ) < x ) {
                oddTransitions = !oddTransitions;          
            }
        }
    }
    return oddTransitions;
}


}

现在,如果你有一个奇怪的形状,你应该能够准确地检测到,如果使用接触它。我已经多次使用此方法。

我使用多边形类来检测旋转位图上的触摸。它主要基于这个网站的信息和代码。这应该适用于您的代码

public class Polygon {

// Polygon coodinates.
private final int[] polyY, polyX;

// Number of sides in the polygon.
private final int polySides;

/**
 * Default constructor.
 * @param px Polygon y coods.
 * @param py Polygon x coods.
 * @param ps Polygon sides count.
 */
public Polygon( final int[] px, final int[] py, final int ps ) {
    polyX = px;
    polyY = py;
    polySides = ps;
}

/**
 * Checks if the Polygon contains a point.
 * @see "http://alienryderflex.com/polygon/"
 * @param x Point horizontal pos.
 * @param y Point vertical pos.
 * @return Point is in Poly flag.
 */
public boolean contains( final float x, final float y ) {

    boolean oddTransitions = false;
    for( int i = 0, j = polySides -1; i < polySides; j = i++ ) {
        if( ( polyY[ i ] < y && polyY[ j ] >= y ) || ( polyY[ j ] < y && polyY[ i ] >= y ) ) {
            if( polyX[ i ] + ( y - polyY[ i ] ) / ( polyY[ j ] - polyY[ i ] ) * ( polyX[ j ] - polyX[ i ] ) < x ) {
                oddTransitions = !oddTransitions;          
            }
        }
    }
    return oddTransitions;
}


}

现在,如果你有一个奇怪的形状,你应该能够准确地检测到,如果使用接触它。我已经多次使用此方法。

您是否在寻找一种方法来判断触摸事件是否落在绘制位图的不透明部分?如果是这样,为什么不将触摸坐标映射到位图上的适当像素并测试颜色呢


如果是这样的话,那么你可以跳过所有路径剪辑的内容,因为你发布的链接只是为了克服模拟器效率低下的问题。

你是否在寻找一种方法来判断触摸事件是否落在绘制位图的不透明部分?如果是这样,为什么不将触摸坐标映射到位图上的适当像素并测试颜色呢


如果是这样的话,那么你可以跳过所有路径剪辑的内容,因为你发布的链接只是为了克服模拟器的低效率。

这有点复杂,所以我不会提供完整的源代码,但我会给你一个想法

您需要将形状转移到三角形集合中,然后触摸找到形状的最近点,并检查您的形状是否位于该点三角形内

对于搜索和排序点,可以使用结构


搜索算法最终应该是O(log(N)),创建形状结构应该是O(N*log(N))

这有点复杂,所以我不打算提供完整的源代码,但我会给你一个想法

您需要将形状转移到三角形集合中,然后触摸找到形状的最近点,并检查您的形状是否位于该点三角形内

对于搜索和排序点,可以使用结构


搜索算法最终应该是O(log(N)),创建形状结构应该是O(N*log(N))

谢谢你的回复。我做了一些修改,它对我有用。我能够在画布上绘制点阵列,并在移动时将触摸事件映射到画布上。再次感谢你,伙计。@theJosh你能帮我解决这个问题吗?谢谢你的回答。通过做一些修改,它对我有效。我能够在画布上绘制点阵列,并在移动时将触摸事件映射到画布上。再次感谢你,伙计。@theJosh,你能帮我解决这个问题吗
public class Polygon {

// Polygon coodinates.
private final int[] polyY, polyX;

// Number of sides in the polygon.
private final int polySides;

/**
 * Default constructor.
 * @param px Polygon y coods.
 * @param py Polygon x coods.
 * @param ps Polygon sides count.
 */
public Polygon( final int[] px, final int[] py, final int ps ) {
    polyX = px;
    polyY = py;
    polySides = ps;
}

/**
 * Checks if the Polygon contains a point.
 * @see "http://alienryderflex.com/polygon/"
 * @param x Point horizontal pos.
 * @param y Point vertical pos.
 * @return Point is in Poly flag.
 */
public boolean contains( final float x, final float y ) {

    boolean oddTransitions = false;
    for( int i = 0, j = polySides -1; i < polySides; j = i++ ) {
        if( ( polyY[ i ] < y && polyY[ j ] >= y ) || ( polyY[ j ] < y && polyY[ i ] >= y ) ) {
            if( polyX[ i ] + ( y - polyY[ i ] ) / ( polyY[ j ] - polyY[ i ] ) * ( polyX[ j ] - polyX[ i ] ) < x ) {
                oddTransitions = !oddTransitions;          
            }
        }
    }
    return oddTransitions;
}


}
public Polygon(Point[] points){
    polySides = points.length;
    polyY = new int[polySides];
    polyX = new int[polySides];

    for(int i = 0; i < polySides; i++){
        polyY[i] = points[i].y;
        polyX[i] = points[i].x;
    }
}
 public boolean isTouched(final float X, final float Y){
   final Polygon p = new Polygon(points);
      return p.contains(X, Y);
}