更新时间:2022-04-26 21:59:16
在你的函数 drawSpiral
中,你在第四行:
In your function drawSpiral
, in the fourth line you do:
b = Math.sqrt(((c.x - b.x) * (c.x - b.x)) + ((c.y - b.y) * (c.y - b.y)));
所以, b
现在应该是一个标量,但是你试着在下一行中访问 bx
和,这不再存在了:
So, b
should be a scalar now, but then you try to access b.x
and b.y
in the next line, which don't exist anymore:
d = 1 / Math.sqrt(((c.x - b.x) * (c.x - b.x)) + ((c.y - b.y) * (c.y - b.y)));
这种情况再次发生在6中的 c
-7行。这可能就是您的代码无法正常工作的原因。
This happens again with c
in the 6-7th lines. This might be why your code isn't working.
我尝试使用我自己的代码。我完全不确定数学,但是我根据你在@ Blindman67的答案中使用的一些鼠标跟踪代码将我的算法基于你在问题上发布的片段。
I tried to make it work with my own code. I'm not sure at all about the math, but I based my algorithm on the snippet you posted on the question, using some of the mouse-tracking code from @Blindman67's answer.
这是重要的部分。它返回一个带有螺旋点的数组(我使用另一个函数来实际渲染它们)。我们的想法是使用您提供的连续斐波纳契函数绘制螺旋线。它从A点开始并强制缩放,使得一圈的半径是A点和B点之间的距离。它还增加了一个角度偏移,因此一圈的角度是A点和B点之间的角度。
This is the important part. It returns an array with the spiral's points (I use another function to actually render them). The idea is to draw a spiral using the continuous-fibonacci function you provided. It starts at point A and forces the scaling so that the radius at one turn is the distance between point A and point B. It also adds an angle offset so the angle at one turn is the angle between point A and B.
编辑以发表评论:我将 for
循环更改为而
循环继续绘制,直到螺旋达到最大半径。我还更改了一些名称并添加了注释以尝试使算法更清晰。
Edited to address comment: I changed the for
loop to a while
loop that continues drawing until the spiral reaches a maximum radius. I also changed some names and added comments to try to make the algorithm clearer.
var getSpiral = function(pA, pB, maxRadius){
// 1 step = 1/4 turn or 90º
var precision = 50; // Lines to draw in each 1/4 turn
var stepB = 4; // Steps to get to point B
var angleToPointB = getAngle(pA,pB); // Angle between pA and pB
var distToPointB = getDistance(pA,pB); // Distance between pA and pB
var fibonacci = new FibonacciGenerator();
// Find scale so that the last point of the curve is at distance to pB
var radiusB = fibonacci.getNumber(stepB);
var scale = distToPointB / radiusB;
// Find angle offset so that last point of the curve is at angle to pB
var angleOffset = angleToPointB - stepB * Math.PI / 2;
var path = [];
var i, step , radius, angle;
// Start at the center
i = step = radius = angle = 0;
// Continue drawing until reaching maximum radius
while (radius * scale <= maxRadius){
path.push({
x: scale * radius * Math.cos(angle + angleOffset) + pA.x,
y: scale * radius * Math.sin(angle + angleOffset) + pA.y
});
i++; // Next point
step = i / precision; // 1/4 turns at point
radius = fibonacci.getNumber(step); // Radius of Fibonacci spiral
angle = step * Math.PI / 2; // Radians at point
}
return path;
};
要生成的代码连续的斐波那契数字基本上是你的,但我改了一些名字来帮助我理解它。我还添加了一个生成器函数,因此它可以处理任何数字:
The code to generate the continuous fibonacci numbers is basically yours, but I changed some names to help me understand it. I also added a generator function so it could work up to any number:
var FibonacciGenerator = function(){
var thisFibonacci = this;
// Start with 0 1 2... instead of the real sequence 0 1 1 2...
thisFibonacci.array = [0, 1, 2];
thisFibonacci.getDiscrete = function(n){
// If the Fibonacci number is not in the array, calculate it
while (n >= thisFibonacci.array.length){
var length = thisFibonacci.array.length;
var nextFibonacci = thisFibonacci.array[length - 1] + thisFibonacci.array[length - 2];
thisFibonacci.array.push(nextFibonacci);
}
return thisFibonacci.array[n];
};
thisFibonacci.getNumber = function(n){
var floor = Math.floor(n);
var ceil = Math.ceil(n);
if (Math.floor(n) == n){
return thisFibonacci.getDiscrete(n);
}
var a = Math.pow(n - floor, 1.15);
var fibFloor = thisFibonacci.getDiscrete(floor);
var fibCeil = thisFibonacci.getDiscrete(ceil);
return fibFloor + a * (fibCeil - fibFloor);
};
return thisFibonacci;
};
To使代码更清晰,我使用了几个辅助函数来处理2D点:
To make code clearer, I used a couple helper functions to work with 2D points:
var getDistance = function(p1, p2){
return Math.sqrt(Math.pow(p1.x-p2.x, 2) + Math.pow(p1.y-p2.y, 2));
};
var getAngle = function(p1, p2){
return Math.atan2(p2.y-p1.y, p2.x-p1.x);
};
整件事: JSFiddle 和更新到地址 - 评论JSFiddle