【问题标题】:How to position a ring of circles with a maximum ring radius如何定位具有最大圆环半径的圆环
【发布时间】:2014-10-08 11:17:18
【问题描述】:

我正在尝试创建一个圆圈,阿拉:

圆有一个给定的半径,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 也可以是 minRingRadiusapproximateRingRadius。但是ringRadius 应该定义下一个最近的“环”,它可以容纳整数个圆圈。


已解决: 解决方案的视觉确认

【问题讨论】:

    标签: c# unity3d 2d trigonometry unity3d-2dtools


    【解决方案1】:

    如果我正确理解了您的问题,应该这样做:

     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 无法检查是否相等,因为总会出现表示错误。

    更新 哎呀,我没看到你也在询问定位圈子的问题。一旦你知道了环的半径和中心角,它就非常简单了。

    【讨论】:

    • 优秀。谢谢!效果很好。我已经有了在我的问题中对圆圈进行最终定位的代码,所以这部分无论如何都是多余的:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-21
    相关资源
    最近更新 更多