algorithm - 在螺旋上绘制等距点

标签 algorithm draw algebra spiral

我需要一种算法来计算点在螺旋路径上的分布。

这个算法的输入参数应该是:

  • 环的宽度(与最内层环的距离)
  • 固定点之间的距离
  • 要绘制的点数

绘制的螺线是阿基米德螺线,得到的点之间必须等距

算法应该打印出单点的笛卡尔坐标序列,例如:

点 1:(0.0) 第 2 点:(...,...) ………… N 点 (..., ...)

编程语言并不重要,非常感谢所有帮助!

编辑:

我已经从这个站点获取并修改了这个示例:

    //
//
// centerX-- X origin of the spiral.
// centerY-- Y origin of the spiral.
// radius--- Distance from origin to outer arm.
// sides---- Number of points or sides along the spiral's arm.
// coils---- Number of coils or full rotations. (Positive numbers spin clockwise, negative numbers spin counter-clockwise)
// rotation- Overall rotation of the spiral. ('0'=no rotation, '1'=360 degrees, '180/360'=180 degrees)
//
void SetBlockDisposition(float centerX, float centerY, float radius, float sides, float coils, float rotation)
{
    //
    // How far to step away from center for each side.
    var awayStep = radius/sides;
    //
    // How far to rotate around center for each side.
    var aroundStep = coils/sides;// 0 to 1 based.
    //
    // Convert aroundStep to radians.
    var aroundRadians = aroundStep * 2 * Mathf.PI;
    //
    // Convert rotation to radians.
    rotation *= 2 * Mathf.PI;
    //
    // For every side, step around and away from center.
    for(var i=1; i<=sides; i++){

        //
        // How far away from center
        var away = i * awayStep;
        //
        // How far around the center.
        var around = i * aroundRadians + rotation;
        //
        // Convert 'around' and 'away' to X and Y.
        var x = centerX + Mathf.Cos(around) * away;
        var y = centerY + Mathf.Sin(around) * away;
        //
        // Now that you know it, do it.

        DoSome(x,y);
    }
}

但是点的配置是错误的,点之间不是等距的。

Spiral with non equidistant distribution

正确的分布示例是左图:

Sirals

最佳答案

对于第一个近似值——这可能足以绘制足够近的 block ——螺旋线是一个圆,并按 chord/radius 的比率增加角度。

// value of theta corresponding to end of last coil
final double thetaMax = coils * 2 * Math.PI;

// How far to step away from center for each side.
final double awayStep = radius / thetaMax;

// distance between points to plot
final double chord = 10;

DoSome ( centerX, centerY );

// For every side, step around and away from center.
// start at the angle corresponding to a distance of chord
// away from centre.
for ( double theta = chord / awayStep; theta <= thetaMax; ) {
    //
    // How far away from center
    double away = awayStep * theta;
    //
    // How far around the center.
    double around = theta + rotation;
    //
    // Convert 'around' and 'away' to X and Y.
    double x = centerX + Math.cos ( around ) * away;
    double y = centerY + Math.sin ( around ) * away;
    //
    // Now that you know it, do it.
    DoSome ( x, y );

    // to a first approximation, the points are on a circle
    // so the angle between them is chord/radius
    theta += chord / away;
}

10 coil spiral

但是,对于较松散的螺旋,您必须更准确地求解路径距离,因为空间太宽,连续点的 awaychord 之间的差异非常显着: 1 coil spiral 1st approximation 1 coil spiral 2nd approximation

上面的第二个版本使用基于使用 theta 和 theta+delta 的平均半径求解 delta 的步骤:

// take theta2 = theta + delta and use average value of away
// away2 = away + awayStep * delta 
// delta = 2 * chord / ( away + away2 )
// delta = 2 * chord / ( 2*away + awayStep * delta )
// ( 2*away + awayStep * delta ) * delta = 2 * chord 
// awayStep * delta ** 2 + 2*away * delta - 2 * chord = 0
// plug into quadratic formula
// a= awayStep; b = 2*away; c = -2*chord

double delta = ( -2 * away + Math.sqrt ( 4 * away * away + 8 * awayStep * chord ) ) / ( 2 * awayStep );

theta += delta;

为了在松散的螺旋上获得更好的结果,请使用数字迭代解决方案来找到计算距离在适当公差范围内的 delta 值。

关于algorithm - 在螺旋上绘制等距点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13894715/

相关文章:

python - 在列表列表中查找重叠列表

javascript - Canvas 绘画应用程序不绘图(Javascript)

haskell - 使用基于整数 Haskell 的 newtypes 执行代数

c++ - 离散化线的算法

python - 将查询与已知列表匹配的算法,根据词典顺序呈现结果

java - 找出两百万以下所有素数的总和。我的程序不适用于非常大的数字

arrays - 从二维字符数组打印所有可能的单词

android - 如何使用 Canvas 重绘选项菜单图标

linux - 如何从 GTK cairo 中的函数发出 "draw"信号

prolog - 我很好奇逻辑程序是否可以做代数