我有两条线相交于已知坐标的点 - x1,y1 - x2,y2 - x3,y3
由此我计算了线之间给定半径的圆弧。所以我现在知道 - 2 个圆弧端点 x4,y4 和 x5,y5 - 圆弧中心点 Cx,Cy - 圆弧半径 r - 相对于极坐标 X 轴的起始和结束角度,因此是线之间的角度。
我想创建一个公式来计算弧的最大和最小 X 和 Y 值。即包围圆弧的盒子的坐标。
在下面的例子中,我可以找到最小X值和最大Y值,它们是已知值,但不确定如何计算最大X和最小Y。
在其他情况下,弧可以是任何坐标,因此已知的最小值和最大值将会改变。
我知道如何计算沿弧线给定角度或间隔的点,但不知道特定方向(在本例中为 X 轴和 Y 轴)上的最大值和最小值。
我将在编程中使用该公式。
小智 6
假设我们有起始角\xce\xb81、结束角\xce\xb82(均为弧度)、半径r、弧线逆时针方向。我们想要找到Xmax、Ymax、Xmin和Ymin。将此值视为象限 q=f(\xce\xb8) 的函数:
\n\nXmax=f(q1,q2,r),Ymax=f(q1,q2,r),Xmin=f(q1,q2,r),Ymin=f(q1,q2,r)。
\n\n不用编写大量的“if”语句,可以方便地将这个函数表示为“极值矩阵”。评估函数 f(q1,q2,r) 我们最终会得到这个矩阵。
\n\n所以这是算法:
\n\n这是我的 C#6 实现:
\n\nusing System;\nusing System.Windows;\nusing static System.Math;\n\npublic static class GeomTools\n{\n public static Byte GetQuadrant(this Double angle)\n {\n var trueAngle = angle%(2*PI);\n if (trueAngle >= 0.0 && trueAngle < PI/2.0)\n return 1;\n if (trueAngle >= PI/2.0 && trueAngle < PI)\n return 2;\n if (trueAngle >= PI && trueAngle < PI*3.0/2.0)\n return 3;\n if (trueAngle >= PI*3.0/2.0 && trueAngle < PI*2)\n return 4;\n return 0;\n }\n public static Rect GetBounds(Double startAngle, Double endAngle, Double r)\n {\n var startQuad = startAngle.GetQuadrant() - 1;\n var endQuad = endAngle.GetQuadrant() - 1;\n\n // Convert to Cartesian coordinates.\n var stPt = new Point(Round(r*Cos(startAngle), 14), Round(r*Sin(startAngle), 14));\n var enPt = new Point(Round(r*Cos(endAngle), 14), Round(r*Sin(endAngle), 14));\n\n // Find bounding box excluding extremum.\n var minX = stPt.X;\n var minY = stPt.Y;\n var maxX = stPt.X;\n var maxY = stPt.Y;\n if (maxX < enPt.X) maxX = enPt.X;\n if (maxY < enPt.Y) maxY = enPt.Y;\n if (minX > enPt.X) minX = enPt.X;\n if (minY > enPt.Y) minY = enPt.Y;\n\n // Build extremum matrices.\n var xMax = new[,] {{maxX, r, r, r}, {maxX, maxX, r, r}, {maxX, maxX, maxX, r}, {maxX, maxX, maxX, maxX}};\n var yMax = new[,] {{maxY, maxY, maxY, maxY}, {r, maxY, r, r}, {r, maxY, maxY, r}, {r, maxY, maxY, maxY}};\n var xMin = new[,] {{minX, -r, minX, minX}, {minX, minX, minX, minX}, {-r, -r, minX, -r}, {-r, -r, minX, minX}};\n var yMin = new[,] {{minY, -r, -r, minY}, {minY, minY, -r, minY}, {minY, minY, minY, minY}, {-r, -r, -r, minY}};\n\n // Select desired values\n var startPt =new Point(xMin[endQuad, startQuad], yMin[endQuad, startQuad]);\n var endPt=new Point(xMax[endQuad, startQuad], yMax[endQuad, startQuad]);\n return new Rect(startPt,endPt);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n对于位于 (0,0) 的圆弧中心点来说是公平的,但您可以轻松地将生成的边界框移动到 Cx,Cy。
\n\n与Tim Buegeleisen的近似解决方案不同,该解决方案是精确的,尽管它可能会消耗更多的内存。
\n