gpt4 book ai didi

javascript - 构造一圈嵌套方 block

转载 作者:太空宇宙 更新时间:2023-11-04 14:01:59 25 4
gpt4 key购买 nike

我想像这样构建一个嵌套正方形的圆圈:

circleOfSquares

目前,我正在使用 JavaScript/HTML5 canvas 进行编程。这是我的代码:

<html>
<head>
<title>Circle of squares</title>
<script type="text/javascript">
var r = 150, u = 20, nests = 200; //radius in pixels, circumference in squares, nests in squares
var w = r; //any number != 0

function getNewW()
{
if(u < 3)
alert("Error: u < 3 (" + u + " < 3)!");

var tangents = new Array(new Array(0, w/2), new Array(Math.sin((1/u*360)*(Math.PI/180))*(w/2), -Math.cos((1/u*360)*(Math.PI/180))*(w/2)));
var sta = new Array(new Array(r, 0), new Array(Math.cos((1/u*360)*(Math.PI/180))*r, Math.sin((1/u*360)*(Math.PI/180))*r));
var end = new Array(new Array(sta[0][0]+tangents[0][0], sta[0][1]+tangents[0][1]), new Array(sta[1][0]+tangents[1][0], sta[1][1]+tangents[1][1]));
var pts = new Array(sta[0], end[0], sta[1], end[1]);
var intersect = new Array(((pts[0][0]*pts[1][1]-pts[0][1]*pts[1][0])*(pts[2][0]-pts[3][0]) - (pts[0][0]-pts[1][0])*(pts[2][0]*pts[3][1]-pts[2][1]*pts[3][0])) / ((pts[0][0]-pts[1][0])*(pts[2][1]-pts[3][1]) - (pts[0][1]-pts[1][1])*(pts[2][0]-pts[3][0])), ((pts[0][0]*pts[1][1]-pts[0][1]*pts[1][0])*(pts[2][1]-pts[3][1]) - (pts[0][1]-pts[1][1])*(pts[2][0]*pts[3][1]-pts[2][1]*pts[3][0])) / ((pts[0][0]-pts[1][0])*(pts[2][1]-pts[3][1]) - (pts[0][1]-pts[1][1])*(pts[2][0]-pts[3][0]))); //Formula from http://en.wikipedia.org/wiki/Line%E2%80%93line_intersection


//distTo0 should be equal to distTo1
var distTo0 = Math.sqrt(Math.pow(sta[0][0]-intersect[0], 2) + Math.pow(sta[0][1]-intersect[1], 2));
var distTo1 = Math.sqrt(Math.pow(sta[1][0]-intersect[0], 2) + Math.pow(sta[1][1]-intersect[1], 2));
if(Math.round(distTo0*100)/100 != Math.round(distTo1*100)/100)
alert("Error: distTo0 != distTo1 (" + distTo0 + " != " + distTo1 + ")!");

return distTo0*2;
}

function start()
{
var canvas = document.getElementById("outputCanvas");

canvas.setAttribute("width", 600);
canvas.setAttribute("height", 600);

if(canvas.getContext)
{
var ctx = canvas.getContext("2d");
ctx.translate(300, 300);

w = getNewW();
for(var i=0; i<u; i++)
{
ctx.rotate((1/u*360)*(Math.PI/180));
ctx.fillRect(r, -w/2, w, w);
}

for(var j=1; j<nests; j++)
{
var oldr = r;
var temp1 = 1/(10*j+1);
while(r+w > oldr) //This is the while-loop that makes the program slow
{
r -= temp1;
w = getNewW();
}
if(r < 0) //When the radius gets smaller than 0, the center is reached -> no new squares have to be drawn
break;

var temp2 = (1/u*360)*(Math.PI/180);
for(var i=0; i<u; i++)
{
ctx.rotate(temp2);
ctx.fillRect(r, -w/2, w, w);
}
}
}
}
</script>
</head>
<body id="main" onload="start()">
<canvas style="border:1px #000000 solid;" width="0" height="0" id="outputCanvas">Canvas not supported...</canvas>
<div id="info"> </div>
</body>
</html>

但是因为我没有解决方案的公式,所以我使用 while 循环来越来越接近解决方案(直到它由于 float 不准确而达到零),这就是它非常慢的原因。那么,可以使用什么公式 来计算(思想)圆内下一个正方形的宽度,如果有必要,如何在其他地方优化代码?

最佳答案

在圆心附近,正方形足够小的地方,您可以用弧长来近似边长 (w) - 即,一个 u 有多长 如果您将其绘制为实际圆圈,那么内圈的第一个。这只是以弧度为单位的 Angular (2 π/u) 乘以穿过正方形内 Angular 的圆的半径。由于您的代码中有 r 变化,我会立即调用正在考虑的特定半径值 r2;这使得弧长成为:

w_approx = (2 * Math.PI / u) * r2

但是对于你图片中的大部分正方形,它与w的实际值相差太大;如果你用它作为边长,你会得到重叠的正方形。幸运的是,我们也可以直接计算出 w 的真实值;它只需要一点三 Angular 学知识。

如果从正方形的内 Angular 到圆心画线,那两条线加上正方形的内侧就形成了一个三 Angular 形。我们知道刚才画的那两条线有多长;它们等于内径。我们不知道第三条边有多长 - 这就是我们正在寻找的 w 的值 - 但我们知道它对面的 Angular 。这三个信息足以计算w

这是一张图片来说明我在说什么:

enter image description here

圆心的 Angular ,在图中标记为 α(alpha),只是一个完整圆的 u,即 2 π/u 弧度(或 360/u 度,但三 Angular 函数都需要弧度):

alpha = 2 * Math.PI / u

三 Angular 形的另外两个 Angular 相等(它们必须相等,因为它们是等长的对边),所以它们都标记为β。由于三 Angular 形的三个内 Angular 总和为 π 弧度(或 180º),因此我们可以计算出 β;它等于 (π - α)/2 弧度:

beta = (Math.PI - alpha)/2

通过Law of Sines ,如果您用任何三 Angular 形的任何边的长度除以该边对 Angular 的正弦值,则无论您选择三个边中的哪一个,结果都是相同的。这告诉我们 w/sin α 必须与 r2/sin 相同> β。求解 w 的方程式可以得到:

w = r2 * Math.sin(alpha) / Math.sin(beta)

关于javascript - 构造一圈嵌套方 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27607179/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com