Javascript web中绘制Fibonacci时出错
目前,我从Blindman67获得了这张图,它绘制了图1(见下图)Javascript web中绘制Fibonacci时出错,javascript,math,geometry,2d,computational-geometry,Javascript,Math,Geometry,2d,Computational Geometry,目前,我从Blindman67获得了这张图,它绘制了图1(见下图) 函数renderSpiral(点A、点B、转角){ 变量dx,dy,rad,i,ang,cx,cy,dist,a,c,angleStep,numberTurns,nTFPB,scale,style; //清理画布 clearRect(0,0,ctx.canvas.width,ctx.canvas.height) //螺旋状物 a=1;//此数字越大,螺旋线越大 c=1.358456;//常数见https://en.wikiped
函数renderSpiral(点A、点B、转角){
变量dx,dy,rad,i,ang,cx,cy,dist,a,c,angleStep,numberTurns,nTFPB,scale,style;
//清理画布
clearRect(0,0,ctx.canvas.width,ctx.canvas.height)
//螺旋状物
a=1;//此数字越大,螺旋线越大
c=1.358456;//常数见https://en.wikipedia.org/wiki/Golden_spiral
angleStep=Math.PI/20;//设置绘图的角度结果
numberTurns=6;//绘制的总半圈数
nTFPB=2;//numberOfTurnsForPointB是指向该点的圈数
//B应该是整数,并描述了数字off
//在到达B点之前转弯
//从A点到B点获取ang
ang=Math.atan2(pointB.y-pointA.y,pointB.x-pointA.x);
//计算从A到B的距离
dist=Math.sqrt(Math.pow(pointB.y-pointA.y,2)+Math.pow(pointB.x-pointA.x,2));
if(dist==0){
return;//这没有任何意义,因此退出时不需要绘制任何内容
}
//获取点B处的螺旋半径
rad=Math.pow(c,ang+nTFPB*2*Math.PI);//点2处的螺旋半径
//现在只需要得到正确的比例,这样螺旋拳就可以
//需要限制。
刻度=距离/弧度;
//A调整圈数,使螺旋线填满画布
while(Math.pow(c,Math.PI*numberTurns)*比例 对于(i=0;i,这里有一把小提琴,我相信它能提供您想要的输出
主要问题是在初始直线上从0结果开始螺旋
从1开始螺旋线将删除图形的这一部分,然后您只需调整黑色| AB |线的起点
这是通过调整
for( i = 0; i <= Math.PI *numberTurns; i+= angleStep)
到
要使| AB |线匹配。要获得所需的特性,需要调整螺旋线,如下所示:
选择直线的直角位置AB
我为A
选择1.5*M\u PI[rad]
,为B
选择3.5*M\u PI[rad]
(在非旋转螺旋上)
通过AB
直线的角度旋转螺旋线
这很简单,只需将角度添加到最终极坐标的笛卡尔坐标转换中,即可旋转整个螺旋,因此螺旋上计算的A,B
的角度位置将与实际点AB
方向匹配
重新缩放螺旋以匹配AB
大小
因此,计算螺旋上的角点A
,B
位置的半径,然后计算比例=|AB |-(r(B)-r(A))
。现在只需将其相乘即可计算每个渲染点的半径
我玩了一点黄金比例,玩了一点螺旋,结果如下
黄色
螺旋线是四分之一圆圆弧的近似值
Aqua
是黄金螺旋
正如你所看到的,它们不太匹配(这是用比率*0.75
使它们更相似,但应该是比率
),或者我在某个地方有一个bug,或者螺旋的原点被移动了(但看起来不像)或者我有错误的比率常数ratio=0.3063489
,或者金色矩形引入了比我教的更高的浮动圆误差,或者我遗漏了一些愚蠢的东西
这里的C++源代码,这样你就可以提取你需要的:
//---------------------------------------------------------------------------
#include <Math.h>
//---------------------------------------------------------------------------
bool _redraw=false; // just signal to repaint window after spiral change
double Ax,Ay,Bx,By; // mouse eddited points
double gr=0.75; // golden spiral ratio scale should be 1 !!!
void GoldenSpiral_draw(TCanvas *can) // GDI draw
{
double a0,a,b,l,x,y,r=5,ratio;
// draw AB line
can->Pen->Color=clWhite;
can->MoveTo(Ax,Ay);
can->LineTo(Bx,By);
// draw A,B points
can->Pen->Color=clBlue;
can->Brush->Color=clAqua;
can->Ellipse(Ax-r,Ay-r,Ax+r,Ay+r);
can->Ellipse(Bx-r,By-r,Bx+r,By+r);
// draw golden ratio rectangles
can->Pen->Color=clDkGray;
can->Brush->Style=bsClear;
ratio=1.6180339887;
a=5.0; b=a/ratio; x=Ax; y=Ay;
y-=0.5*b; x-=0.5*b; // bias to match real golden spiral
can->Rectangle(x,y,x+a,y+b); y-=a;
for (int i=0;i<5;i++)
{
can->Rectangle(x,y,x+a,y+a); b=a; a*=ratio; x-=a;
can->Rectangle(x,y,x+a,y+a); y+=a; b=a; a*=ratio;
can->Rectangle(x,y,x+a,y+a); x+=a; y-=b; b=a; a*=ratio;
can->Rectangle(x,y,x+a,y+a); x-=b; b=a; a*=ratio; y-=a;
}
// draw circle arc approximation of golden spiral
ratio=1.6180339887;
a=5.0; b=a/ratio; x=Ax; y=Ay; r=10000; y-=a;
y-=0.5*b; x-=0.5*b; // bias to match real golden spiral
can->Pen->Color=clYellow;
for (int i=0;i<5;i++)
{
can->Arc(x-a,y,x+a,y+a+a,+r, 0, 0,-r); b=a; a*=ratio; x-=a;
can->Arc(x,y,x+a+a,y+a+a, 0,-r,-r, 0); y+=a; b=a; a*=ratio;
can->Arc(x,y-a,x+a+a,y+a,-r, 0, 0,+r); x+=a; y-=b; b=a; a*=ratio;
can->Arc(x-a,y-a,x+a,y+a, 0,+r,+r, 0); x-=b; b=a; a*=ratio; y-=a;
}
can->Brush->Style=bsSolid;
// compute golden spiral parameters
ratio=0.3063489*gr;
x=Bx-Ax;
y=By-Ay;
l=sqrt(x*x+y*y); // l=|AB|
if (l<1.0) return; // prevent domain errors
a0=atan2(-y,x); // a=atan2(AB)
a0+=0.5*M_PI; // offset so direction of AB matches the normal
a=1.5*M_PI; r=a*exp(ratio*a); b=r;
a+=2.0*M_PI; r=a*exp(ratio*a); b=r-b;
b=l/r; // b=zoom of spiral to match AB screw distance
// draw golden spiral
can->Pen->Color=clAqua;
can->MoveTo(Ax,Ay);
for (a=0.0;a<100.0*M_PI;a+=0.001)
{
r=a*b*exp(ratio*a); if (r>512.0) break;
x=Ax+r*cos(a0+a);
y=Ay-r*sin(a0+a);
can->LineTo(x,y);
}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#包括
//---------------------------------------------------------------------------
bool _redraw=false;//只需在螺旋线更改后发出重新绘制窗口的信号
双轴,Ay,Bx,By;//鼠标旋转点
double gr=0.75;//黄金螺旋比率刻度应为1!!!
void GoldenSpiral_draw(TCanvas*can)//GDI draw
{
双a0,a,b,l,x,y,r=5,比率;
//画AB线
can->Pen->Color=clWhite;
can->MoveTo(Ax,Ay);
can->LineTo(Bx,By);
//画A、B点
can->Pen->Color=clBlue;
罐头->刷子->颜色=clAqua;
can->椭圆(Ax-r、Ay-r、Ax+r、Ay+r);
can->椭圆(Bx-r、By-r、Bx+r、By+r);
//绘制黄金比例矩形
can->Pen->Color=clDkGray;
可以->画笔->样式=b清除;
比率=1.6180339887;
a=5.0;b=a/比率;x=Ax;y=Ay;
y-=0.5*b;x-=0.5*b;//偏置以匹配真正的黄金螺旋
can->矩形(x,y,x+a,y+b);y-=a;
对于(inti=0;iRectangle(x,y,x+a,y+a);b=a;a*=比率;x-=a;
can->矩形(x,y,x+a,y+a);y+=a;b=a;a*=比率;
can->矩形(x,y,x+a,y+a);x+=a;y-=b;b=a;a*=比率;
can->矩形(x,y,x+a,y+a);x-=b;b=a;a*=比率;y-=a;
}
//绘制黄金螺线的圆弧逼近
比率=1.6180339887;
a=5.0;b=a/比率;x=Ax;y=Ay;r=10000;y-=a;
y-=0.5*b;x-=0.5*b;//匹配re的偏差
for( i = 1; i <= Math.PI *numberTurns; i+= angleStep)
// ready to draw
ctx.beginPath();
ctx.moveTo(0, 0) // start at center
// ready to draw
ctx.beginPath();
dx = Math.cos(1); // get the vector for angle i
dy = Math.sin(1);
var rad = Math.pow(c, 1); // calculate the radius
ctx.moveTo(dx * rad, dy * rad ) // start at center
//---------------------------------------------------------------------------
#include <Math.h>
//---------------------------------------------------------------------------
bool _redraw=false; // just signal to repaint window after spiral change
double Ax,Ay,Bx,By; // mouse eddited points
double gr=0.75; // golden spiral ratio scale should be 1 !!!
void GoldenSpiral_draw(TCanvas *can) // GDI draw
{
double a0,a,b,l,x,y,r=5,ratio;
// draw AB line
can->Pen->Color=clWhite;
can->MoveTo(Ax,Ay);
can->LineTo(Bx,By);
// draw A,B points
can->Pen->Color=clBlue;
can->Brush->Color=clAqua;
can->Ellipse(Ax-r,Ay-r,Ax+r,Ay+r);
can->Ellipse(Bx-r,By-r,Bx+r,By+r);
// draw golden ratio rectangles
can->Pen->Color=clDkGray;
can->Brush->Style=bsClear;
ratio=1.6180339887;
a=5.0; b=a/ratio; x=Ax; y=Ay;
y-=0.5*b; x-=0.5*b; // bias to match real golden spiral
can->Rectangle(x,y,x+a,y+b); y-=a;
for (int i=0;i<5;i++)
{
can->Rectangle(x,y,x+a,y+a); b=a; a*=ratio; x-=a;
can->Rectangle(x,y,x+a,y+a); y+=a; b=a; a*=ratio;
can->Rectangle(x,y,x+a,y+a); x+=a; y-=b; b=a; a*=ratio;
can->Rectangle(x,y,x+a,y+a); x-=b; b=a; a*=ratio; y-=a;
}
// draw circle arc approximation of golden spiral
ratio=1.6180339887;
a=5.0; b=a/ratio; x=Ax; y=Ay; r=10000; y-=a;
y-=0.5*b; x-=0.5*b; // bias to match real golden spiral
can->Pen->Color=clYellow;
for (int i=0;i<5;i++)
{
can->Arc(x-a,y,x+a,y+a+a,+r, 0, 0,-r); b=a; a*=ratio; x-=a;
can->Arc(x,y,x+a+a,y+a+a, 0,-r,-r, 0); y+=a; b=a; a*=ratio;
can->Arc(x,y-a,x+a+a,y+a,-r, 0, 0,+r); x+=a; y-=b; b=a; a*=ratio;
can->Arc(x-a,y-a,x+a,y+a, 0,+r,+r, 0); x-=b; b=a; a*=ratio; y-=a;
}
can->Brush->Style=bsSolid;
// compute golden spiral parameters
ratio=0.3063489*gr;
x=Bx-Ax;
y=By-Ay;
l=sqrt(x*x+y*y); // l=|AB|
if (l<1.0) return; // prevent domain errors
a0=atan2(-y,x); // a=atan2(AB)
a0+=0.5*M_PI; // offset so direction of AB matches the normal
a=1.5*M_PI; r=a*exp(ratio*a); b=r;
a+=2.0*M_PI; r=a*exp(ratio*a); b=r-b;
b=l/r; // b=zoom of spiral to match AB screw distance
// draw golden spiral
can->Pen->Color=clAqua;
can->MoveTo(Ax,Ay);
for (a=0.0;a<100.0*M_PI;a+=0.001)
{
r=a*b*exp(ratio*a); if (r>512.0) break;
x=Ax+r*cos(a0+a);
y=Ay-r*sin(a0+a);
can->LineTo(x,y);
}
}
//---------------------------------------------------------------------------