public static bool RotatedRectangleGetNearestIntersectionPoint(RectangleF r, float angle, PointF p1, PointF p2, out PointF result)
{
if (angle == 0)
{
return GoObject.GetNearestIntersectionPoint(r, p1, p2, out result);
}
double rad = angle * Math.PI / 180;
double cosine = Math.Cos(rad);
double sine = Math.Sin(rad);
PointF center = new PointF(r.X + r.Width / 2, r.Y + r.Height / 2);
PointF otl = new PointF(r.X, r.Y);
PointF a = RotatePoint(otl, center, cosine, sine);
PointF otr = new PointF(r.X + r.Width, r.Y);
PointF b = RotatePoint(otr, center, cosine, sine);
PointF obr = new PointF(r.X + r.Width, r.Y + r.Height);
PointF c = RotatePoint(obr, center, cosine, sine);
PointF obl = new PointF(r.X, r.Y + r.Height);
PointF d = RotatePoint(obl, center, cosine, sine);
// This is the given point, who knows where...
float Cx = p1.X;
float Cy = p1.Y;
PointF P;
float closestdist = 10e20f;
PointF closestpoint = new PointF();
if (GoStroke.NearestIntersectionOnLine(a, b, p1, p2, out P))
{
// calculate the (non-square-rooted) distance from C to P
float dist = (P.X - Cx) * (P.X - Cx) + (P.Y - Cy) * (P.Y - Cy);
if (dist < closestdist)
{
closestdist = dist;
closestpoint = P;
}
}
if (GoStroke.NearestIntersectionOnLine(b, c, p1, p2, out P))
{
float dist = (P.X - Cx) * (P.X - Cx) + (P.Y - Cy) * (P.Y - Cy);
if (dist < closestdist)
{
closestdist = dist;
closestpoint = P;
}
}
if (GoStroke.NearestIntersectionOnLine(c, d, p1, p2, out P))
{
float dist = (P.X - Cx) * (P.X - Cx) + (P.Y - Cy) * (P.Y - Cy);
if (dist < closestdist)
{
closestdist = dist;
closestpoint = P;
}
}
if (GoStroke.NearestIntersectionOnLine(d, a, p1, p2, out P))
{
float dist = (P.X - Cx) * (P.X - Cx) + (P.Y - Cy) * (P.Y - Cy);
if (dist < closestdist)
{
closestdist = dist;
closestpoint = P;
}
}
result = closestpoint;
return (closestdist < 10e20f);
}
} // end of RotationHelper
}
namespace Graphic
{
public class Form1 : Form
{
public class RectTest : GoRectangle
{
public override void AddSelectionHandles(GoSelection sel, GoObject selectedObj)
{
RotationHelper.AddResizeHandles(this, this.Angle, sel, selectedObj);
}
private class GraphicsStateController : IDisposable
{
private Graphics g;
private GraphicsState before;
public GraphicsStateController(Graphics g)
{
this.g = g;
this.before = g.Save();
}
public void Dispose()
{
this.g.Restore(this.before);
}
}
public override void Paint(Graphics g, GoView view)
{
if (Math.Abs(this.Angle) > float.Epsilon)
{
using (new GraphicsStateController(g))
{
PointF c = this.Center;
g.TranslateTransform(c.X, c.Y);
g.RotateTransform(this.Angle);
g.TranslateTransform(-c.X, -c.Y);
base.Paint(g, view);
}
}
else
{
base.Paint(g, view);
}
}
public override RectangleF ExpandPaintBounds(RectangleF rect, GoView view)
{
RectangleF b = RotationHelper.GetRotatedBounds(rect, this.Angle);
b.Inflate(1, 1);//Vergrößert dieses Rectangle um den angegebenen Betrag.
return RectangleF.Union(rect, b);
}
public override bool ContainsPoint(PointF p)
{
return RotationHelper.RotatedRectangleContainsPoint(this.Bounds, this.Angle, p);
}
public override bool ContainedByRectangle(RectangleF r)
{
return RotationHelper.RotatedRectangleContainedByRectangle(this.Bounds, this.Angle, r);
}
public override bool GetNearestIntersectionPoint(PointF p1, PointF p2, out PointF result)
{
return RotationHelper.RotatedRectangleGetNearestIntersectionPoint(this.Bounds, this.Angle, p1, p2, out result);
}
public override IGoHandle CreateBoundingHandle()
{
GoHandle h = new GoHandle();
RectangleF rect = RotationHelper.GetRotatedBounds(this.Bounds, this.Angle);
// the handle rectangle should just go around the object
rect.X--;
rect.Y--;
rect.Height += 2;
rect.Width += 2;
h.Bounds = rect;
return h;
}
public void Rotate(PointF rotatePoint, float angle)
{
PointF q = RotationHelper.RotatePoint(this.Center, rotatePoint, angle);
this.Center = q;
this.Angle += angle;
}
[Category("Appearance"), DefaultValue(0)]
public float Angle
{
get { return myAngle; }
set
{
float old = myAngle;
if (old != value)
{
myAngle = value;
Changed(ChangedAngle, 0, null, MakeRect(old), 0, null, MakeRect(value));
}
}
}
public override void ChangeValue(GoChangedEventArgs e, bool undo)
{
if (e.SubHint == ChangedAngle)
{
this.Angle = e.GetFloat(undo);
}
else
{
base.ChangeValue(e, undo);
}
}
public const int ChangedAngle = GoObject.LastChangedHint + 2;
private float myAngle = 0;
}
public Form1()
{
GoView myView = new GoView();
if(myView.DragsRealtime == false)
{
myView.DragsRealtime = true;
}
myView.Dock = DockStyle.Fill;
this.Controls.Add(myView);
RectTest rect = new RectTest();
PointF f = rect.Center;
rect.Rotate(f,30);
rect.Brush = Brushes.Black;
myView.Document.Add(rect);
}
}
}
thank you Jake