借鉴螺旋等距点 [英] Draw equidistant points on a spiral

查看:433
本文介绍了借鉴螺旋等距点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need an algorithm to calculate the distribution of points on a spiral path.

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

The input parameters of this algorithm should be:

  • 宽度循环(从最里面的循环距离)
  • 固定点之间的距离
  • 在点数画

画螺旋是阿基米德螺线,并获得一定的点数等距从对方。

The spiral to draw is an archimedean spiral and the points obtained must be equidistant from each other.

该算法应该打印出单一的点的直角坐标的序列,例如:

The algorithm should print out the sequence of the Cartesian coordinates of single points, for example:

点1:(0.0) 要点2:(...,...) ........ N点(...,...)

Point 1: (0.0) Point 2: (..., ...) ........ Point N (..., ...)

编程语言并不重要,都有助于大大AP preciated!

The programming language isn't important and all help greatly appreciated!

编辑:

我已经获得和修改这个例子从该网站:

I already get and modify this example from this site:

    //
//
// 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);
    }
}

但点的配置是错误的,点不相互等距。

But the disposition of point is wrong, the points aren't equidistant from each other.

正确的分布的例子是在左边的图像:

The correct distribution example is is the image on the left:

推荐答案

要第一个近似值 - 这可能是够绘制足够接近块好 - 螺旋是一个圆,由比率和弦/半径。

To a first approximation - which is probably good enough for plotting blocks close enough - the spiral is a circle and increment the angle by the ratio 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;
}

然而,对于一个宽松的螺旋,你将有更准确地解决路径距离的空间过大,其中以<$比较的的差别远的连续点是显著C $ C>和弦:

However, for a looser spiral you will have to solve the path distance more accurately as spaces too wide where the difference between away for successive points is significant compared with chord:

的第二个版本以上使用基于基于使用平均半径为THETA和θ+增量求解增量的步骤:

The second version above uses a step based on solving for delta based on using the average radius for theta and theta+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;

有关松散螺旋更好的结果,使用数值迭代求解寻找增量的值,其中计算的距离在一个合适的容差。

For even better results on a loose spiral, use a numeric iterative solution to find the value of delta where the calculated distance is within a suitable tolerance.

这篇关于借鉴螺旋等距点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆