HitTest For Path

I am currently in the process of creating a component which is essentially an XY pad but as a triangle shape. To set the location of the marker inside, I’d assume I need to do a hitTest to check whether the location of the mouse click is within the bounds of the triangle path.

However after about an hour playing around with the hitTest I can’t seem to understand how to go about this. Could somebody point me in the right direction?

Is there a way to roll your own using the Line class?

maybe define the triangle as 3 Lines, and then compare your mouse x/y position against each of those lines to see if it’s within the bounds of the triangle?

https://juce.com/doc/classLine
and the MouseEvent::getPosition() method should get you where you need to be.

You can use a Path object to help you out.

for example…

Path triangle;
triangle.addTriangle (...); // add points of trianlge
triangle.contains (...); // add the point you wish to check is inside the triangle
3 Likes

This is the process I’m currently working on and starting to get working. Currently struggling to get to grasps with checking if two paths are intersecting to prevent the marker from going over the triangle path when the mouse is at the edge

Anthony’s suggestion should work.

Make your triangle a class member, so you can access it from inside your class’s mouse event handlers.

void mouseMove( const MouseEvent& event) 
{
   if( triangle.contains( event.getPosition ) ) ...
}

https://juce.com/doc/classPath#a9f45cde60e4ac827073f4b8ffe1245b7

1 Like

Already on it :slight_smile: Thanks both!

If your Component has a triangle drawn… in hitTest you can do something like:

 bool CMyComponent::hitTest (int x, int y)
 {
     Colour pixelColour = m_Image.getPixelAt (x, y);

     if (pixelColour.isTransparent())
         return false;

     return true;
 }

Rail

Cheers for the suggestion Rail. I might use this in the future, however the current version of the component only uses the triangle as an outline and the rest is a different solid colour (or transparent maybe?)

Triangle

Well, first semester solution for convex polygons:
Go each line segment and see the scalar product, like “is left of line”…
You just need to know if it is clockwise or anti clockwise.

    Array<Point<float>> points;
    points.add (Point<float> (10, 10));
    points.add (Point<float> (20, 10));
    points.add (Point<float> (20, 20));

    Point<float> x (15, 15);

    for (int i=0; i<points.size(); ++i) {
        auto current = points [i];
        auto next    = points [i + 1 % points.size()];
        if ((next - current).getDotProduct (x - current) < 0)
            return false;
    }
    return true;

EDIT: seems to miss the point, sorry :wink:

Back to the question, I think hitTest is only called at mouseClick, not when dragging. But you should be able to call hitTest yourself in the dragging callback, maybe?

I’ve completely forgone the hitTest for now, using path.contains instead to check the bounds of the triangle. Would the hitTest be appropriate to pass mouseEvents to components behind the transparent area of the Triangle?

Yes, IIRC when the mouse is clicked over a Component, it will call hitTest. If this returns true, the mouseDown callback is called, otherwise it tries on the parent component.
I don’t know how about siblings though…

Yes, if hitTest returns false, it’ll try whatever is the next thing behind that point. Could be the parent, could be a sibling that’s further back in the Z-order.