我正在尝试创建一个圆圈,ala:
圆具有给定的半径circleRadius
。环的最大半径为maxRingRadius
。圆数可以是需要计算的任何整数circles
,以及圆环的实际半径ringRadius
。圆环的中心距圆环中心ringRadius
单位时,应如图所示精确接触。
给定一个circleRadius
和maxRingRadius
,如何找到最接近(或倒数第二个)的ringRadius
将适合整数circles
,然后定位这些圆?
static Vector3[] RingOfCircles(float maxRingRadius, float circleRadius) {
//int circles = ...; // calculate this?
//float ringRadius = ...; // calculate this?
//Edit: Solution. These three lines are adapted from InBetween's GetNextSmallerRingRadius function but Unity3d-ized and without validation
int circles = Mathf.RoundToInt(Mathf.PI / Mathf.Asin(circleRadius / maxRingRadius));
float centralAngle = 2 * Mathf.PI / (numberOfCircles - 1);
float ringRadius = circleRadius / Mathf.Sin(centralAngle / 2);
// create ring of center points
float radsPerCircle = (Mathf.PI * 2) / circles;
Vector3[] centerPoints = new Vector3[circles];
for (int i=0; i < circles; i++) {
float angle = i * radsPerCircle;
centerPoints[i] = new Vector3(
Mathf.Sin(angle) * ringRadius,
Mathf.Cos(angle) * ringRadius,
0);
}
return centerPoints;
}
`
注意:出于我的目的,
maxRingRadius
也可以是minRingRadius
或approximateRingRadius
。但是ringRadius
应该定义可以容纳整数个圆的下一个最近的“环”。解决了:
视觉确认解决方案
最佳答案
如果我正确理解了您的问题,则应该这样做:
public static double GetNextSmallerRingRadius(double startingRingRadius, double circleRadius)
{
Debug.Assert(startingRingRadius >= 0);
Debug.Assert(circleRadius > 0);
int currentNumberOfCircles = GetCurrentNumberOfCircles(startingRingRadius, circleRadius);
//Let's get trivial cases out of the way
if (currentNumberOfCircles == 1)
throw new ArgumentException();
if (currentNumberOfCircles == 2)
return 0; //trivial solution for 1 circle.
if (currentNumberOfCircles == 3)
return circleRadius; //trivial solution for 2 circles.
double centralAngle = 2 * Math.PI / (currentNumberOfCircles - 1);
return circleRadius / Math.Sin(centralAngle / 2);
}
public static double GetNextLargerRingRadius(double startingRingRadius, double circleRadius)
{
Debug.Assert(startingRingRadius >= 0);
Debug.Assert(circleRadius > 0);
int currentNumberOfCircles = GetCurrentNumberOfCircles(startingRingRadius, circleRadius);
//Let's get trivial cases out of the way
if (currentNumberOfCircles == 1)
return circleRadius; //trivial solution for 2 circles.
double centralAngle = 2 * Math.PI / (currentNumberOfCircles + 1);
return circleRadius / Math.Sin(centralAngle / 2);
}
private static int GetCurrentNumberOfCircles(double startingRingRadius, double circleRadius)
{
if (startingRingRadius == 0)
{
return 1;
}
else
{
return (int)Math.Round(Math.PI / Math.Asin(circleRadius / startingRingRadius), 0); //There would need to be some logic to make sure input values are correct.
}
}
要验证输入(定义的半径代表有效的解决方案),您可以比较舍入的和未舍入的
numberOfcircles
,并确保差值在给定的公差范围内。请记住,使用double
不能检查是否相等,因为始终会出现表示错误。更新糟糕,我没有看到您也在询问有关放置圆圈的问题。一旦您知道了环的半径和圆心角,就非常简单了。
关于c# - 如何放置最大圆环半径的圆环,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26255590/