как связать набор точек (пользовательские фигуры) и прикоснуться к нему на андроид - PullRequest
1 голос
/ 02 января 2012

я могу получить свой точечный набор точек (в виде массива), используя эту ссылку Теперь мой вопрос: как я могу связать эти точки как форму / регион? Означает, что когда пользователь коснулся области моих ограниченных точек, я хочу перемещать объекты (фигуры) в соответствии с этим. Над точкой возврата ссылки цветного растрового изображения (она удаляет прозрачную часть) в качестве массива возвращаются только цветные точки детали. Это то, что мой код:

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));
        }
    }
}

}

2) MyShapre.java

class MyShape{
    CustomShape customShape ;
    Point points[];
    private int x, y;
    Path path = new Path();
    public MyShape(Context context) {           
        customShape = new CustomShape(ScaleTestActivity.this);
        points = new Point[customShape.getPoints().size()];
        for(int i=0;i<customShape.getPoints().size();i++){
            points[i] = new Point();
            points[i] = customShape.getPoints().get(i); 
        }
    }
    public Path getPath(){
        return path;
    }

    public void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        Paint paint = new Paint();
        paint.setColor(Color.WHITE);
        for(int i =0 ;i<points.length;i++){             
            Point point = new Point(points[i].x + getX(), points[i].y + getY());
            path.lineTo(points[i].x, points[i].y);
            canvas.drawPoint(point.x,point.y,paint);
        }
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getX() {
        return x;
    }
    public void setY(int y) {
        this.y = y;
    }
    public int getY() {
        return y;
    }       
}

}

3) MainPanel.java

    class MainPanel extends View{
        Context context;
        MyShape myShape;
        boolean flag = false;
        public MainPanel(Context context) {         
            super(context);
            this.context = context;
            myShape = new MyShape(context);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawColor(Color.RED);
            myShape.onDraw(canvas);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            // TODO Auto-generated method stub          
            int x,y;
            x = (int)event.getX();
            y = (int)event.getY();
            Point point = new Point(x, y);

            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                myShape.setX(x);
                myShape.setY(y);
                RectF rectF = new RectF();
                Path path = myShape.getPath();
                path.computeBounds(rectF, true);
                Region region = new Region();

                region.setPath(path, new Region((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom));

                if(region.contains(x,y)){
                    flag = true;
                    Log.i("System out","onDown");
                }
                break;
            case MotionEvent.ACTION_MOVE:               
                Log.i("System out","onMove : "+flag);
                if(flag){
                    myShape.setX(x);
                    myShape.setY(y);
                    Log.i("System out","onMove");
                }
                break;
            case MotionEvent.ACTION_UP:
//              myShape.setX(x);
//              myShape.setY(y);
                flag = false;
                Log.i("System out","onUp");
                break;
            default:
                break;
            }
            invalidate();
            return true;
        }
    }

4) ScaleTestActivity.java

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

Ответы [ 3 ]

5 голосов
/ 14 января 2012

Я использую класс Polygon для обнаружения касаний вращающихся растровых изображений. Он основан в основном на информации и коде с этого сайта http://alienryderflex.com/polygon/. Это должно работать с вашим кодом.

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;
}


}

Вы можете добавить этот конструктор, чтобы помочь вам преобразовать массив Point в объект Polygon.

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;
    }
}

Возможно, вы сможете использовать его в своем классе MyShape с этим методом.

 public boolean isTouched(final float X, final float Y){
   final Polygon p = new Polygon(points);
      return p.contains(X, Y);
}

Теперь, если у вас странная форма, вы сможете точно определить, касается ли ее использование. Я использовал этот метод много раз.

2 голосов
/ 17 января 2012

Вы ищете способ определить, происходит ли событие касания в непрозрачной части вашего нарисованного растрового изображения?Если так, то почему бы вам просто не отобразить координату касания на соответствующий пиксель на растровом изображении и проверить цвет?

И если это так, то вы можете пропустить все элементы отсечения пути, так как ссылкаВы опубликовали, только делает это, чтобы преодолеть неэффективность эмулятора.

1 голос
/ 18 января 2012

Это немного сложно, поэтому я не собираюсь предоставлять полный исходный код, но я дам вам идею.

Вам нужно перенести свою форму в коллекцию треугольников, а затем коснуться найти ближайшую точкусвоей формы и проверьте, находитесь ли вы внутри этого точечного треугольника.

Для поиска и сортировки точек вы можете использовать красно-черно-красное дерево структура.

Алгоритм поискав конечном итоге должно быть в O (log (N)) и создание структуры формы должно быть O (N * Log (N))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...