private PtV FarthestPointToPoint(RectV rect, PointF pt) { return new PtV() { X = pt.X < rect.W / 2 ? (Func<double, double>)rect.Right : (Func<double, double>)rect.Left, Y = pt.Y < rect.H / 2 ? (Func<double, double>)rect.Bottom : (Func<double, double>)rect.Top }; }
private void MaxTextRegion(Size size, CircleF circle, double angle, double fratio, out float mxlen, out PointF center) { // ew(Ex-Width)=(len*fratio)/2 // half-rect // { w=ew+len*|cosa|/2 // h=ew+len*|sina|/2 } // { c0=... // c1=... } double vx = Math.Cos(angle); double vy = Math.Sin(angle); double c0 = (fratio + Math.Abs(vx)) / 2; double c1 = (fratio + Math.Abs(vy)) / 2; double mxlenx = Math.Min(size.Width / (2 * c0), size.Height / (2 * c1)); RectV rect = new RectV() { C0 = c0, C1 = c1, W = size.Width, H = size.Height }; PtV fp = FarthestPointToPoint(rect, circle.Center); float cx = circle.Center.X, cy = circle.Center.Y; double l = 0, r = mxlenx; Point2D c = new Point2D(cx, cy); for (int i = 0; i < 16; i++) { double mid = (l + r) / 2; double px = fp.X(mid); double py = fp.Y(mid); double px0 = px + vx * mid / 2; double py0 = py + vy * mid / 2; double px1 = px - vx * mid / 2; double py1 = py - vy * mid / 2; Line2D line = new Line2D(new Point2D(px0, py0), new Point2D(px1, py1)); Point2D cp = line.ClosestPointTo(c, true); if (cp.DistanceTo(c) < circle.Radius + mid * fratio / 2) { r = mid; } else { l = mid; } } mxlenx = (l + r) / 2; mxlen = (float)mxlenx; center = new PointF((float)fp.X(mxlenx), (float)fp.Y(mxlenx)); }