阿基米德螺旋线

1,311 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

image.png

阿基米德螺线是一个点匀速离开一个固定点的同时又以固定的角速度绕该固定点转动而产生的轨迹。 阿基米德螺旋线公式:

  • 极坐标方程为: r = a + bθ
  • 平面笛卡尔坐标方程式为: x = (a + bθ)cos(θ), y = (a + bθ)sin(θ)
    • a: 当θ=0°时的极径(mm)
    • b: 阿基米德螺旋线系数(mm/°),表示每旋转1度时极径的增加/减小量
    • θ: 极角,单位为度,表示阿基米德螺旋线转过的总度数(弧度)
  • 当θ=0时,a为起点到极坐标原点的距离,改变参数a将改变螺线形状;
  • b为螺旋线每增加单位角度r随之对应增加的数值,控制相邻螺线之间的距离,通常其为常量。

Unity测试代码,绘制LineRenderer:

public class AchimedeanSpiral : MonoBehaviour
{
    //极坐标方程为: r = a + bθ
    //平面笛卡尔坐标方程式为: x = (a + bθ)cos(θ), y = (a + bθ)sin(θ)
    //a: 当θ=0°时的极径(mm)
    //b: 阿基米德螺旋线系数(mm/°),表示每旋转1度时极径的增加/减小量
    //θ: 极角,单位为度,表示阿基米德螺旋线转过的总度数(弧度)
    //改变参数a将改变螺线形状,b控制螺线间距离,通常其为常量
 
    //公式参数
    [SerializeField] float parameA = 1;
    [SerializeField] float parameB = 1;
    [SerializeField] float parameAngle = 2 * Mathf.PI;
 
    //Z值变化
    [SerializeField] float spiralHeightAdded = 0.5f;
 
    //取点间隔角度(弧度)
    [SerializeField] float intervalAngle = 0.1f;
 
    //保存取样点
    List<Vector3> spiralPointList = new List<Vector3>();
 
    //绘制曲线
    [SerializeField] LineRenderer lineRenderer;
 
    void Update()
    {
        if (Input.GetMouseButtonDown(1))
            DrawSpiral();
    }
 
    void DrawSpiral()
    {
        spiralPointList.Clear();
 
        //隔固定角度取样
        float drawAngle = 0;
        while (drawAngle <= parameAngle)
        {
            spiralPointList.Add(GetPointByAngle(drawAngle));
            drawAngle += intervalAngle;
        }
 
        lineRenderer.positionCount = spiralPointList.Count;
        lineRenderer.SetPositions(spiralPointList.ToArray());
    }
 
    float tempX, tempY, tempZ;
    Vector3 GetPointByAngle(float angle)
    {
        //公式计算坐标
        tempX = (parameA + parameB * angle) * Mathf.Cos(angle);
        tempY = (parameA + parameB * angle) * Mathf.Sin(angle);
        //Z值增量
        tempZ = spiralHeightAdded * angle;
        return new Vector3(tempX, tempY, tempZ);
    }
 
}

绘制结果展示:

image.png

image.png