1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| /**
* C#
*/
// MAGICAL CONSTANT to map ellipse to beziers
// 2/3*(sqrt(2)-1)
const double Ellipse2Beziers = 0.2761423749154;
// GDI Bitmap
using var bitmap = new System.Drawing.Bitmap(width, height);
using var graphics = System.Drawing.Graphics.FromImage(bitmap);
// 椭圆的4个顶点
PointF[] ellipse = new PointF[4] { point1, point2, point3, point4 };
// 两个轴的长度
double r1 = ellipse[2].DistanceTo(ellipse[3]);
double r2 = ellipse[0].DistanceTo(ellipse[1]);
// 旋转角度
double angle = -SysMath.Atan2(ellipse[2].Y - ellipse[3].Y, ellipse[2].X - ellipse[3].X);
double sin = SysMath.Sin(angle);
double cos = SysMath.Cos(angle);
// 贝塞尔曲线控制点相对于中心点的偏移长度
SizeF offset = new SizeF((float)(r1 * Ellipse2Beziers), (float)(r2 * Ellipse2Beziers));
// 椭圆中心点
PointF center = new PointF((ellipse[0].X + ellipse[1].X) / 2f, (ellipse[0].Y + ellipse[1].Y) / 2f);
// 贝塞尔曲线的控制点
PointF[] beziers = new PointF[13]
{
new PointF((float)(center.X - r1 / 2.0), center.Y),
new PointF((float)(center.X - r1 / 2.0), center.Y - offset.Height),
new PointF(center.X - offset.Width, (float)(center.Y - r2 / 2.0)),
new PointF(center.X, (float)(center.Y - r2 / 2.0)),
new PointF(center.X + offset.Width, (float)(center.Y - r2 / 2.0)),
new PointF((float)(center.X + r1 / 2.0), center.Y - offset.Height),
new PointF((float)(center.X + r1 / 2.0), center.Y),
new PointF((float)(center.X + r1 / 2.0), center.Y + offset.Height),
new PointF(center.X + offset.Width, (float)(center.Y + r2 / 2.0)),
new PointF(center.X, (float)(center.Y + r2 / 2.0)),
new PointF(center.X - offset.Width, (float)(center.Y + r2 / 2.0)),
new PointF((float)(center.X - r1 / 2.0), center.Y + offset.Height),
new PointF((float)(center.X - r1 / 2.0), center.Y)
};
// 旋转变换
double offsetX = center.X - center.X * cos - center.Y * sin;
double offsetY = center.Y + center.X * sin - center.Y * cos;
for (int j = 0; j < beziers.Length; j++)
{
beziers[j] = new PointF(
(float)(beziers[j].X * cos + beziers[j].Y * sin + offsetX),
(float)(beziers[j].Y * cos - beziers[j].X * sin + offsetY));
}
// 绘制曲线
graphics.DrawBeziers(new Pen(Brushes.White, 1f)/* Pen */, beziers);
|