2

I create a GraphicsPath object, add a ellipse, rotate the GraphicsPath object and then draw it. Now I want to get for example the leftmost Point of the graphicsPath has so I can check if it is within certain boundaries (users can move the graphicsPath with the mouse).

I am currently using the GetBounds() method from the GraphicsPath but that only result in the following

image.

The blue is the rectangle from GetBounds() so as you can tell there is some space between the leftmost Point i get from this method compared to the Point I want. How can I get the Point I'm looking for instead?

Taxen0
  • 55
  • 8
  • You will either need to learn about [bezier curves](https://en.wikipedia.org/wiki/B%C3%A9zier_curve) and how to solve the system of equations to find the outermost point. Or you do a hit-test for a particular pixel color on each pixel (slow as hell) – Psi Aug 14 '17 at 13:49
  • How do you rotate? You can rotate the Graphics object or the GraphicsPath? – TaW Aug 14 '17 at 19:10
  • @Psi [Well...](https://math.stackexchange.com/a/91304) – Vector Sigma Mar 24 '20 at 00:33

1 Answers1

1

If you actually rotate the GraphicsPath you can use the Flatten function to aquire a large number of path points. Then you can select the minimum x-value and from it the corresponding y-value.

This will work since you have an ellipse, so only one point can be the most leftmost..

enter image description here

private void panel1_Paint(object sender, PaintEventArgs e)
{
    GraphicsPath gp = new GraphicsPath();
    gp.AddEllipse(77, 55, 222, 77);

    Rectangle r = Rectangle.Round(gp.GetBounds());
    e.Graphics.DrawRectangle(Pens.LightPink, r);
    e.Graphics.DrawPath(Pens.CadetBlue, gp);

    Matrix m = new Matrix();
    m.Rotate(25);
    gp.Transform(m);
    e.Graphics.DrawPath(Pens.DarkSeaGreen, gp);
    Rectangle rr = Rectangle.Round(gp.GetBounds());
    e.Graphics.DrawRectangle(Pens.Fuchsia, rr);

    GraphicsPath gpf = (GraphicsPath)gp.Clone();
    gpf.Flatten();
    float mix = gpf.PathPoints.Select(x => x.X).Min();
    float miy = gpf.PathPoints.Where(x => x.X == mix).Select(x => x.Y).First();
    e.Graphics.DrawEllipse(Pens.Red, mix - 2, miy - 2, 4, 4);
}

Please don't ask me why the rotated bounds are so wide - I really don't know!

If instead you rotate the Graphics object before drawing you may still use the same trick..

TaW
  • 53,122
  • 8
  • 69
  • 111
  • Thank you, this worked perfectly! I was indeed rotating the GraphicsPath like above and the Flatten function was what I was missing. It seems the bounds are too large because they also include the controlpoints for the curves, – Taxen0 Aug 15 '17 at 07:41
  • _It seems the bounds are too large because they also include the controlpoints for the curves_ Hm sounds plausible. But: It still is wide for the flattended path which should contains only lines. I'll to a few tests later.. – TaW Aug 15 '17 at 16:01