可以看到根据算出来的开始角和摆动角,再带入计算出来的弧线(关于计算弧线的算法可以参考我之前的博客)是跟之前的弧线一致的,也间接验证了算法的准确性
求Arc的椭圆圆心求圆心公式如下:
则代码如下:
/// <summary> /// 获取弧线的椭圆圆心 /// </summary> /// <param>起点X</param> /// <param>起点Y</param> /// <param>终点X</param> /// <param>终点Y</param> /// <param>优劣弧:1 优弧 0劣弧</param> /// <param>顺逆时针绘制:1 顺时针 0 逆时针</param> /// <param>椭圆半长轴</param> /// <param>椭圆半短轴</param> /// <param>旋转角</param> /// <returns></returns> private static Point GetArcCenterPoint(double x1, double y1, double x2, double y2, double fA, double fs, double rx, double ry, double φ) { var matrix1 = new Matrix { M11 = Math.Cos(φ), M12 = Math.Sin(φ), M21 = -Math.Sin(φ), M22 = Math.Cos(φ) }; var matrix2 = new Matrix { M11 = (x1 - x2) / 2, M21 = (y1 - y2) / 2 }; var matrixX1Y1 = Matrix.Multiply(matrix1, matrix2); var x1_ = matrixX1Y1.M11; var y1_ = matrixX1Y1.M21; var a = Math.Pow(rx, 2) * Math.Pow(ry, 2) - Math.Pow(rx, 2) * Math.Pow(y1_, 2) - Math.Pow(ry, 2) * Math.Pow(x1_, 2); var b = Math.Pow(ry, 2) * Math.Pow(y1_, 2) + Math.Pow(ry, 2) * Math.Pow(x1_, 2); double c = 0; if (fA == fs) { c = -Math.Sqrt(a / b); } else { c = Math.Sqrt(a / b); } var matrixCx_Cy_ = new Matrix { M11 = c * (rx * y1_ / ry), M21 = c * (-ry * x1_ / rx) }; var tempMatrix = new Matrix { M11 = Math.Cos(φ), M12 = -Math.Sin(φ), M21 = Math.Sin(φ), M22 = Math.Cos(φ) }; var multiplyMatrix = Matrix.Multiply(tempMatrix, matrixCx_Cy_); var matrixCxCy=new Matrix(){M11 = multiplyMatrix.M11+((x1+x2)/2),M21= multiplyMatrix.M21+((y1+y2)/2) }; return new Point(matrixCxCy.M11, matrixCxCy.M21); }最终通过上面Svg Arc字符串算出来的椭圆圆心为(-17.42169108128391,-5.368374418803782)
源码BlogCodeSample/OpenxmlActToSvgSample at main · ZhengDaoWang/BlogCodeSample