clutter/point: Add ClutterPoint quarilateral testing API

Add a function to check whether a point is inside a quadrilateral
by checking the cross product of vectors with the quadrilateral
points, and the point being checked.

If the passed quadrilateral is zero-sized, no point is ever reported
to be inside it.

This will be used by the next commit when comparing the transformed
actor vertices.

[feaneron: add a commit message and remove unecessary code]

https://gitlab.gnome.org/GNOME/mutter/merge_requests/189
This commit is contained in:
Daniel van Vugt
2019-07-18 16:56:41 +08:00
committed by Jonas Ådahl
parent fdda8adfcf
commit a70823dd1c
4 changed files with 150 additions and 0 deletions

View File

@ -570,6 +570,68 @@ G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterPoint, clutter_point,
clutter_point_free,
CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_point_progress))
static int
clutter_point_compare_line (const ClutterPoint *p,
const ClutterPoint *a,
const ClutterPoint *b)
{
float x1 = b->x - a->x;
float y1 = b->y - a->y;
float x2 = p->x - a->x;
float y2 = p->y - a->y;
float cross_z = x1 * y2 - y1 * x2;
if (cross_z > 0.f)
return 1;
else if (cross_z < 0.f)
return -1;
else
return 0;
}
/**
* clutter_point_inside_quadrilateral:
* @point: a #ClutterPoint to test
* @vertices: array of vertices of the quadrilateral, in clockwise order,
* from top-left to bottom-left
*
* Determines whether a point is inside the convex quadrilateral provided,
* and not on any of its edges or vertices.
*
* Returns: %TRUE if @point is inside the quadrilateral
*/
gboolean
clutter_point_inside_quadrilateral (const ClutterPoint *point,
const ClutterPoint *vertices)
{
unsigned int i;
int first_side;
first_side = 0;
for (i = 0; i < 4; i++)
{
int side;
side = clutter_point_compare_line (point,
&vertices[i],
&vertices[(i + 1) % 4]);
if (side)
{
if (first_side == 0)
first_side = side;
else if (side != first_side)
return FALSE;
}
}
if (first_side == 0)
return FALSE;
return TRUE;
}
/*

View File

@ -200,6 +200,9 @@ float clutter_point_distance (const ClutterPoint *a,
const ClutterPoint *b,
float *x_distance,
float *y_distance);
CLUTTER_EXPORT
gboolean clutter_point_inside_quadrilateral (const ClutterPoint *point,
const ClutterPoint *vertices);
/**
* ClutterSize: