我正在尝试绘制从“起点”到“终点”的螺旋线.螺旋线还具有给定的中心点,因此可以围绕该中心点绘制螺旋线.
我无法使其工作,以某种方式数学是完全错误的.
关于如何解决这个问题的任何建议?
The jsfiddle of the code I tried is here.
<!DOCTYPE HTML>
<html>
<body>
<canvas id="myCanvas" width="800" height="600" style="border:1px solid #c3c3c3;"></canvas>
<script type="text/javascript">
var c = document.getElementById("myCanvas");
var cxt = c.getContext("2d");
//center of the spiral coords:
var centerX = 400;
var centerY = 300;
//draw the center of spiral point:
drawCirc(centerX,centerY,10,'#6f0c4f');
var gap = 8;
var STEPS_PER_ROTATION = 50;
var rotations = 4;
var increment = rotations * Math.PI / STEPS_PER_ROTATION;
var theta = increment;
//start point:
var startX = 500;
var startY = 380;
//end point:
var endX = 600
var endY = 300;
//draw the start and end points as small circles:
drawCirc(startX,startY,6,'#FF0000');
drawCirc(endX,endY,'#00FF00');
//trying to calculate theta start position:
theta = Math.abs(((centerX - startX) / Math.cos(theta)) / gap);
var ind = 0;
while (theta < rotations * Math.PI * 2) {
var newX = centerX + theta * Math.cos(theta) * gap;
var newY = centerY + theta * Math.sin(theta) * gap;
var ukwObj = { x: newX,y: newY };
if (ind == 0) {
//draw start point with differnt color to differentiate
drawCirc(newX,newY,2,'orange');
} else {
drawCirc(newX,newY);
}
ind++;
theta = theta + increment;
}
function drawCirc(x,y,radius = 2,stroke = '#000000') {
cxt.beginPath();
cxt.arc(x,radius,2 * Math.PI);
cxt.strokeStyle = stroke;
cxt.stroke();
cxt.fillStyle = stroke;
cxt.fill();
}
cxt.stroke(); // draw the spiral
</script>
</body>
</html>
最佳答案
画圆的原理是:
给定中心x,半径r,我们可以通过计算如下坐标来绘制属于圆的点:px = xr * Math.cos(angle)和py = yr * Math.sin(angle)(角度变化时)从0到2 *Math.PI.
如果当角度变化时r增大,我们将得到一个向外的螺旋形(从角度0到角度2 * PI等于0).
给定中心x,半径r,我们可以通过计算如下坐标来绘制属于圆的点:px = xr * Math.cos(angle)和py = yr * Math.sin(angle)(角度变化时)从0到2 *Math.PI.
如果当角度变化时r增大,我们将得到一个向外的螺旋形(从角度0到角度2 * PI等于0).
对于当前的问题,我们需要以极坐标(距离,角度)计算螺旋的开始和结束位置.
因此,我们需要计算起始角度,起始距离,终止角度和终止距离,并通过逐渐增加角度和距离来绘制每个点.
最初的theta计算是错误的,我已经更改了.
然后,我需要计算中心与起点之间的起点距离以及中心与终点之间的终点距离.
在旋转过程中,您的进度会从开始距离到结束距离.
总角度距离应为totalTheta = numberOfRotation * 2 * Math.PI(endAngle-startAngle),我用totalTheta代替了旋转* Math.PI * 2)
只是为了好玩并演示它适用于任何初始条件,我对开始位置,结束位置和转数进行了随机分配.
我还减少了每次迭代的角度增量,以使每个点之间的距离看起来更均匀,但是您可以添加注释以保持恒定的角速度.
下面的解决方案将随机选择一个橙色的点,一个绿色的点,若干匝以完成螺旋,并将围绕固定的紫色点绘制螺旋.
var c = document.getElementById("myCanvas");
var cxt = c.getContext("2d");
//center of the spiral coords:
var centerX = 200;
var centerY = 150;
//draw the center of spiral point:
drawCirc(centerX,'#6f0c4f');
var gap = 8;
var STEPS_PER_ROTATION = 50;
var rotations = 1 + parseInt(Math.random() * 5,10);
var increment = rotations * Math.PI / STEPS_PER_ROTATION;
var theta = increment;
var dist = 0;
//start point:
var startX = centerX + (Math.random() * 150 - 75);
var startY = centerY + (Math.random() * 150 - 75);
var startAngleOffset = startX > centerX ? (startY > centerY ? 0 : 0) : (startY > centerY ? Math.PI : Math.PI);
var startAngleSign = startX > centerX ? (startY > centerY ? 1 : -1) : (startY > centerY ? -1 : 1);
//end point:
var endX = centerX + (Math.random() * 150 - 75);
var endY = centerY + (Math.random() * 150 - 75);
var endAngleOffset = endX > centerX ? (endY > centerY ? 0 : 0) : (endY > centerY ? Math.PI : Math.PI);
var endAngleSign = endX > centerX ? (endY > centerY ? 1 : -1) : (endY > centerY ? -1 : 1);
//draw the start and end points as small circles:
drawCirc(startX,'#00FF00');
var startTheta = theta = startAngleOffset + startAngleSign * Math.atan(Math.abs(startY - centerY)/Math.abs(startX - centerX));
var endTheta = endAngleOffset + endAngleSign * Math.atan(Math.abs(endY - centerY)/Math.abs(endX - centerX));
var totalTheta = rotations * 2 * Math.PI + (endTheta - startTheta)
dist = Math.sqrt(Math.pow(startY - centerY,2) + Math.pow(startX - centerX,2));
finalDist = Math.sqrt(Math.pow(endY - centerY,2) + Math.pow(endX - centerX,2));
var ind = 0;
while (theta -startTheta < totalTheta) {
var currentDist = (dist + ((finalDist - dist)* ((theta - startTheta) / (totalTheta))));
var newX = centerX + currentDist * Math.cos(theta);
var newY = centerY + currentDist * Math.sin(theta);
var ukwObj = { x: newX,newY);
}
ind++;
theta = theta + increment;
// decrement increment to make the space between points look more regular
increment = Math.max(0.01,increment - 0.00096);
}
function drawCirc(x,2 * Math.PI);
cxt.strokeStyle = stroke;
cxt.stroke();
cxt.fillStyle = stroke;
cxt.fill();
}
cxt.stroke(); // draw the spiral
<!DOCTYPE HTML>
<html>
<body>
<canvas id="myCanvas" width="800" height="600" style="border:1px solid #c3c3c3;"></canvas>
</body>
</html>