androidshapesandroid-touch-event

How to recognize touch on a triangle?


I'm trying to recognize if the (x,y) of my finger is touching any part of the triangle object.

This is how I draw the triangle

    public void drawTriangle(Canvas canvas, Paint paint, int x, int y, int width) {
        int halfWidth = width / 2;

        Path path = new Path();
        path.moveTo(x, y - halfWidth); // Top
        path.lineTo(x - halfWidth, y + halfWidth); // Bottom left
        path.lineTo(x + halfWidth, y + halfWidth); // Bottom right
        path.lineTo(x, y - halfWidth); // Back to Top
        path.close();

        canvas.drawPath(path, paint);
    }

This is how I draw to the screen + examples of how I recognize other shapes like square and circle:

       public boolean onTouchEvent(MotionEvent event) {

            int X = (int) event.getX();
            int Y = (int) event.getY();
            int eventaction = event.getAction();
            switch (eventaction) {
                /*
                case MotionEvent.ACTION_DOWN:
                    Toast.makeText(this, "ACTION_DOWN AT COORDS "+"X: "+X+" Y: "+Y, Toast.LENGTH_SHORT).show();
                    isTouch = true;
                    break;

                 */

                case MotionEvent.ACTION_MOVE:
                    {
                        int s = triangle.getY() * triangle.getWidth()/ triangle.getY()-triangle.getWidth()/2;

                        if(X>=circle.getX()-circle.getRadius()&&X<=circle.getX()+circle.getRadius()
                        &&Y>=circle.getY()-circle.getRadius()&&Y<=circle.getY()+circle.getRadius()) {
                            circle.setX(X);
                            circle.setY(Y);
                            //square.setX(X);
                            //square.setY(Y);

                        }
                        if(X < square.getX() + square.getWidth() && X + square.getWidth() > square.getX() &&
                                Y < square.getY() + square.getHeight() && Y + square.getHeight() > square.getY())
                        {

                            square.setX(X);
                            square.setY(Y);

                        }
                        if(//triangle help)
                        {
                            triangle.setX(X);
                            triangle.setY(Y);
                        }
                    break;
                }
                
            }
            return true;
        }

Solution

  • Source link of pseudocode solution.

    There are multiple ways to check if the point is in or out of a triangle.

    Let's say that each of the vertices of a triangle has inner and outer sides. Inner is the one that is inside of a triangle, outer is therefore outside of a triangle.

    To check if a point is inside of a triangle we can check if the point is on the inner side of each triangle vertex. Note: this solution might require some minor changes from you as I do not know the exact structure of your triangle class.

    public boolean onTouchEvent(MotionEvent event) {
    
                int X = (int) event.getX();
                int Y = (int) event.getY();
                int eventaction = event.getAction();
                switch (eventaction) {
    case MotionEvent.ACTION_MOVE:
                        {
                            ...
    
                            int halfWidth = triangle.getWidth()/2;
                            Pair<Integer, Integer> v1 = new Pair(triangle.getX(), triangle.getY() - halfWidth);
                            Pair<Integer, Integer> v2 = new Pair(triangle.getX() - halfWidth, triangle.getY() + haldWidth);
                            Pair<Integer, Integer> v3 = new Pair(triangle.getX() + halfWidth, triangle.getY() + halfWidth);
                            if (isPointInTriangle(x, y, v1, v2, v3)) {
                                // point is inside of a triangle
                            }
                        break;
                    }
                    
                }
                return true;
    }
    
    private int sign(int x, int y, Pair<Integer, Integer> vertex1, Pair<Integer, Integer> vertex2) {
        return (x - vertex2.first) * (vertex1.second - vertex2.second) - (vertex1.first - vertex2.first) * (y - vertex2.second);
    }
    
    private boolean isPointInTriangle(int x, int y, Pair<Integer, Integer> vertex1, Pair<Integer, Integer> vertex2, Pair<Integer, Integer> vertex3)
    {
        int r1 = sign(x, y, vertex1, vertex2);
        int r2 = sign(x, y, vertex2, vertex3);
        int r3 = sign(x, y, vertex3, vertex1);
    
        boolean hasNegative = (r1 < 0) || (r2 < 0) || (r3 < 0);
        boolean hasPositive = (r1 > 0) || (r2 > 0) || (r3 > 0);
    
        return !(hasNegative && hasPositive);
    }