Search code examples
javaandroidpathcontains

Finding Points contained in a Path in Android


Is there a reason that they decided not to add the contains method (for Path) in Android?

I'm wanting to know what points I have in a Path and hoped it was easier than seen here:

How can I tell if a closed path contains a given point?

Would it be better for me to create an ArrayList and add the integers into the array? (I only check the points once in a control statement) Ie. if(myPath.contains(x,y)

So far my options are:

  • Using a Region
  • Using an ArrayList
  • Extending the Class
  • Your suggestion

I'm just looking for the most efficient way I should go about this


Solution

  • I came up against this same problem a little while ago, and after some searching, I found this to be the best solution.

    Java has a Polygon class with a contains() method that would make things really simple. Unfortunately, the java.awt.Polygonclass is not supported in Android. However, I was able to find someone who wrote an equivalent class.

    I don't think you can get the individual points that make up the path from the Android Path class, so you will have to store the data in a different way.

    The class uses a Crossing Number algorithm to determine whether or not the point is inside of the given list of points.

    /**
     * Minimum Polygon class for Android.
     */
    public class Polygon
    {
        // Polygon coodinates.
        private int[] polyY, polyX;
    
        // Number of sides in the polygon.
        private int polySides;
    
        /**
         * Default constructor.
         * @param px Polygon y coods.
         * @param py Polygon x coods.
         * @param ps Polygon sides count.
         */
        public Polygon( int[] px, int[] py, 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( int x, int 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;
        }  
    }