//由三点计算圆弧的参数:
//const QRect & rectangle, int startAngle, int spanAngle
//圆弧的包围框(左上角坐标、宽、高),起始角度、旋转角度
double radius, x0, y0, startAngle, spanAngle;
double x1 = dataList.at(0)->x, x2 = dataList.at(1)->x, x3 = dataList.at(2)->x;
double y1 = dataList.at(0)->y, y2 = dataList.at(1)->y, y3 = dataList.at(2)->y;
double a = x1 - x2;
double b = y1 - y2;
double c = x1 - x3;
double d = y1 - y3;
double e = ((x1 * x1 - x2 * x2) + (y1 * y1 - y2 * y2)) / 2.0;
double f = ((x1 * x1 - x3 * x3) + (y1 * y1 - y3 * y3)) / 2.0;
double det = b * c - a * d;
if ((x1 == x2 && x1 == x3) || (y1 == y2 && y1 == y3))
{
return; //三点一线
}
x0 = (b * f - d * e) / det;
y0 = (c * e - a * f) / det;
radius = hypot(x1 - x0, y1 - y0);
//计算三点的对应的角度
double angle1 = acos((x1 - x0) / (hypot((x1 - x0), (y1 - y0))));
double angle2 = acos((x2 - x0) / (hypot((x2 - x0), (y2 - y0))));
double angle3 = acos((x3 - x0) / (hypot((x3 - x0), (y3 - y0))));
if (y1 - y0 < 0)
angle1 = 2 * PI - angle1; //点1在第三、四象限
if (y2 - y0 < 0)
angle2 = 2 * PI - angle2; //点2在第三、四象限
if (y3 - y0 < 0)
angle3 = 2 * PI - angle3; //点3在第三、四象限
//上面计算的角度是基于QGraphicsView中的坐标,需要进行转换为数学坐标中的角度
angle1 = 360 - angle1 * 180 / PI;
angle2 = 360 - angle2 * 180 / PI;
angle3 = 360 - angle3 * 180 / PI;
//设置绘制方向
startAngle = angle1;
spanAngle = angle3 - angle1;
if (!data->m_arcDirection) //顺时针(负值)
{
if (spanAngle > 0)
spanAngle = spanAngle - 360;
}
else //逆时针(正值)
{
if (spanAngle < 0)
spanAngle = spanAngle + 360;
}
//m_angle圆弧在圆上的起点角度,m_spanAngle圆弧的角度
double arcRecX = x0 - radius;
double arcRecY = y0 - radius;
double arcRecW = 2 * radius;
double arcRecH = 2 * radius;
double arcStartPhi = startAngle;
double arcSpanPhi = spanAngle;
QRect rec;
rec.setX(arcRecX );
rec.setY(arcRecY );
rec.setWidth(arcRecW );
rec.setHeight(arcRecH );
painters.drawArc(rec, 16 * arcStartPhi, 16 * arcSpanPhi); //QT绘制单位就是1/16度,需进行换算