计算机制图——三点画弧
三点画弧相关事件鼠标点击事件private void pictureBox1_MouseClick(object sender, MouseEventArgs e){// 直接在picturebox上点就可以,点够3个就画弧// 可重复点,3个一组Point arcPoint = new Point(e.X, e.Y...
·
三点画弧(C#)
全局变量
- 静态存储
Graphics g;
List<Point> arc = new List<Point>();
相关事件
- 鼠标点击事件
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
// 直接在picturebox上点就可以,点够3个就画弧
// 可重复点,3个一组
Point arcPoint = new Point(e.X, e.Y);
arc.Add(arcPoint);
if (arc.Count == 3)
paintArc(arc); // 自定义函数,见下
}
相关函数
- paintArc
private void paintArc(List<Point> arc)
{
Pen p = new Pen(Color.Black, 1);
// 将点的每个点都显示在窗体上
for (int i = 0; i < 3; i++)
g.DrawEllipse(p, arc[i].X, arc[i].Y, 2, 2);
// ABCDEF为求圆心的辅助变量
int A = arc[0].X - arc[1].X;
int B = arc[0].Y - arc[1].Y;
int C = arc[0].X - arc[2].X;
int D = arc[0].Y - arc[2].Y;
double E = (arc[0].X * arc[0].X - arc[1].X * arc[1].X + arc[0].Y * arc[0].Y - arc[1].Y * arc[1].Y) / 2;
double F = (arc[0].X * arc[0].X - arc[2].X * arc[2].X + arc[0].Y * arc[0].Y - arc[2].Y * arc[2].Y) / 2;
// 利用克拉默法则求圆心
double X = -(D * E - B * F) / (B * C - A * D);
double Y = -(A * F - C * E) / (B * C - A * D);
// 将圆心显示在窗体上
Point center = new Point(Convert.ToInt16(X), Convert.ToInt16(Y));
g.DrawEllipse(p, center.X, center.Y, 2, 2);
// 两点间距离求半径
double R = Math.Sqrt((arc[0].X - X) * (arc[0].X - X) + (arc[0].Y - Y) * (arc[0].Y - Y));
// 求OX与O1, O3间的夹角,顺时针
// 单纯的cos无法判断,需要借助sin
// 且注意y轴指向下
double cosValue1 = (arc[0].X - X) / R;
double sinValue1 = (arc[0].Y - Y) / R;
double angle1 = Math.Acos(cosValue1)/Math.PI*180;
if (sinValue1 < 0)
angle1 = 360 - angle1;
double cosValue2 = (arc[2].X - X) / R;
double sinValue2 = (arc[2].Y - Y) / R;
double angle3 = Math.Acos(cosValue2) / Math.PI * 180;
if (sinValue2 < 0)
angle3 = 360 - angle3;
// 根据矢量叉积判断1、2、3点为顺时针还是逆时针
// mode=1为顺时针
int mode = (arc[1].X - arc[0].X) * (arc[2].Y - arc[1].Y) - (arc[1].Y - arc[0].Y) * (arc[2].X - arc[1].X) > 0 ? 1 : 0;
// 分了四种情况:
// 1、2、3顺时针绘制,角1大于角3 or 角1小于角3
// 1、2、3逆时针绘制,角1大于角3 or 角1小于角3
if (mode == 1)
if (angle3 > angle1)
g.DrawArc(p, (int)(X - R), (int)(Y - R), (int)(2 * R), (int)(2 * R), (float)angle1, (float)(angle3 - angle1));
else
g.DrawArc(p, (int)(X - R), (int)(Y - R), (int)(2 * R), (int)(2 * R), (float)angle1, (float)(360 - (angle1 - angle3)));
else
if (angle3 > angle1)
g.DrawArc(p, (int)(X - R), (int)(Y - R), (int)(2 * R), (int)(2 * R), (float)angle1, (float)(angle3 - angle1 - 360));
else
g.DrawArc(p, (int)(X - R), (int)(Y - R), (int)(2 * R), (int)(2 * R), (float)angle1, (float)(angle3 - angle1));
// 清除掉point链表,以边存储下一组圆弧
arc.Clear();
}
运行结果
- 三点画弧
了解更多访问我的Blog~

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)