Showing posts with label Extension Method. Show all posts
Showing posts with label Extension Method. Show all posts

Monday, March 26, 2012

GraphicsPath.IsVisible() method wont work when using zoom matrix with a big zoom factor in GDI+

When programming for a graphical application, I noticed that the GraphicsPath.IsVisible() method, sometimes,  is not working fine for small path figures when using scale matrix for the Graphics of the object or Control.

I googled for the problem and found a solution in Java. Then I translated the code to C# as an extension method to the GraphicsPath. It works fine now. The translated code is as follows:

/// <summary>
/// Indicates whether the graphics path contains the specified point or not.
/// </summary>
/// <param name="graphicsPath">The graphics path to check if it contains the point.</param>
/// <param name="location">The specified location to check if it is inside the path or not.</param>
/// <returns>True if the point is within the graphics path, otherwise false.</returns>
public static bool Contains(this GraphicsPath graphicsPath, PointF location)
{
    GraphicsPath actualPath = (GraphicsPath)graphicsPath.Clone();
    bool oddTransitions = false;

    actualPath.Flatten(null, .25f);

    for (int i = 0, j = actualPath.PointCount - 1; i < actualPath.PointCount; j = i++)
        if ((actualPath.PathPoints[i].Y < location.Y && actualPath.PathPoints[j].Y >= location.Y) ||
            (actualPath.PathPoints[j].Y < location.Y && actualPath.PathPoints[i].Y >= location.Y))
            if (actualPath.PathPoints[i].X + 
                ((location.Y - actualPath.PathPoints[i].Y) /
                (actualPath.PathPoints[j].Y - actualPath.PathPoints[i].Y) *
                (actualPath.PathPoints[j].X - actualPath.PathPoints[i].X)) < location.X)
                oddTransitions = !oddTransitions;

    return oddTransitions;
}

I cloned and flattened the original path to be sure the result is correct even if it contains Beziers. Hope it can help you.

Enjoy programming.