test for point inside path

Mar 7, 2009 at 4:49pm

test for point inside path

Hi there,

I am using the JGraphics API extensively and I like it a lot.
However, I have noticed that there is no function call to test if a point is inside an arbitrary path.

Specifically, there is not even a function to test if a point is inside a circle.

I know I could use the pt_in_roundedrect function, but it doesn’t seem the best way to go, and it is still not usable for an arbitrary path.

Am I missing something here?

Thanks in advance.

- Luigi

#42721
Mar 10, 2009 at 11:41pm

Please, how do I test if a point is inside or outside a path?

Thanks.

- Luigi

#152932
Aug 11, 2011 at 8:46am

Hi Luigi!

I have the same question and I like to know if you have the answer yet.
Actually I want to do this in svg bezier (path).
Thanks.
Laci

#152933
Aug 11, 2011 at 12:31pm

Hi Luigi,
i was looking into this the other day, to save iterating through a big list of screen button coordinates to ascertain where the mouse is pressed. I tried making a tiny rectangle of the ,ouse position and trying
long jgraphics_rectcontainsrect(t_rect *outer, t_rect *inner);.
I couldn’t get it to work for me, so ended up building a big dictionary of button coordinates to make the iteration a bit easier to follow.
If you get jgraphics_rectcontainsrect to work for you, let me know how – I’ve been so full on with building a big gui that I can’t even remember what exactly was going wrong!!!!
All the best,
Leigh

#152934
Aug 11, 2011 at 1:06pm

Hi guys,

I am not completely sure I understand Leigh’s post, however I don’t think jgraphics_rectcontainsrect() would be the preferred way to go here. In the JGraphics API there’s simply a graphics_ptinrect() function that ought to do what’s needed to test if a point is inside a rectangular area.

If your needs are more complex than that (i.e. test if a point is inside an arbitrary path) here is what I do:

int pt_in_path(t_pt *pt)
{
    t_jsurface *surface;
    t_jgraphics *context;
    int result = 0;

    surface = jgraphics_image_surface_create(JGRAPHICS_FORMAT_A8, 1, 1);
    context = jgraphics_create(surface);

    /*
     * Here is where you draw your path...
     * Remember to close it by calling jgraphics_close_path() at the end.
     */

    result = jgraphics_in_fill(context, pt->x, pt->y);

    jgraphics_destroy(context);
    jgraphics_surface_destroy(surface);

    return result;
}

Basically you create a 1×1 offscreen surface, get the context associated with that surface and then draw the path.
Since a path is just a mathematical entity that has nothing to do with pixels, you don’t use it for drawing, but you let jgraphics_in_fill() calculate for you if the specified point is inside or outside the path.

This works… however I am curious if someone found a better/faster approach, that doesn’t involve creating a surface.

Cheers.

- Luigi

#152935
Aug 11, 2011 at 2:42pm

this is typical problem in computer graphics.

search for “inside polygon”, the Jordan Curve Theorem algorithm below works by looking at intersecting each line of the polygon.

http://sidvind.com/wiki/Point-in-polygon:_Jordan_Curve_Theorem

here’s the function i’m using right now, works quite well:

hth

/*j

bool insidePolygon(point & p)
{
	point p1, p2; // p1, p2 = line; p = current
	float x1, x2;
	int crossings = 0;
	float k, m, y2;
	static const float eps = 0.000001;
	float dx, dy;

	// iterate through each line
	for (int i = 0; i < (numerOfPolyPoints - 1); i++ )
	{
		p1 = map->perimeter[i].relPosition;
		p2 = map->perimeter[i+1].relPosition;
		if ( p1.x < p2.x ) { // same result when going from left to right and right to left
			x1 = p1.x;
			x2 = p2.x;
        } else {
			x1 = p2.x;
			x2 = p1.x;
        }
        // is ray capable of crossing the line ?
        if ( p.x > x1 && p.x < = x2 && ( p.y < p1.y || p.y <= p2.y ) ) {
			dx = p2.x - p1.x; // Calculate the equation of the line
			dy = p2.y - p1.y;
			if ( fabs(dx) < eps ) {
				k = INFINITY;   // defined math.h
			} else {
				k = dy / dx;
			}
			m = p1.y - k * p1.x;
			y2 = k * p.x + m; // ray crosses the line ?
			if ( p.y <= y2 ){
				crossings++;
			}
        }
	}
	if(crossings % 2 == 1) {
		return true;
	} else {
		return false;
	}
}
#152936
Aug 11, 2011 at 3:05pm

Sure, but that works only with polygons.
I was talking about arbitrary paths which could be made of bezier curves as well. [ jgraphics_curve_to() ]

Thanks for sharing your solution anyway.

- Luigi

#152937
Aug 11, 2011 at 3:09pm

well, a bezier curve has to be rendered, so if you know the resolution, you can get the bezier as line-segments. the path has to be closed, anyways, otherwise a point can’t be inside it, right? ;=)

looks complicated, what are you trying to achieve?

/*j

#152938
Aug 12, 2011 at 2:00pm

I’d rather use the resolution independent property of paths since it’s very desirable for the kind of work I am doing. On top of that, it’s flexible, efficient and it integrates nicely with the JGraphics API.

I am not trying to achieve anything in particular. I always like this kind of geometry problem and – above all – I was trying to answer Leigh’s post. In the process I got curious to find out if there was some other approach that could have been better/faster than what I came up with.

I think that – if you want to use the facilities provided by the JGraphics API – there’s not much else that could be done. Maybe if the path struct could be directly accessed by the user more possibilities might be available, but – at least in this version of the SDK – it’s not the case…

Thanks for your input.

Best.

- Luigi

#152939

You must be logged in to reply to this topic.