Javascript 递归金三角,三角形接近哪一点?
我正在尝试制作一个旋转缩放递归金三角。它画一个金三角,然后在里面画另一个,依此类推。这很容易,但挑战在于使其放大并围绕三角形接近的点旋转 为了让它无限放大那个点,我需要想出一个公式来计算三角形接近哪个点 此时正在运行演示: 存储库:Javascript 递归金三角,三角形接近哪一点?,javascript,recursion,math,html5-canvas,trigonometry,Javascript,Recursion,Math,Html5 Canvas,Trigonometry,我正在尝试制作一个旋转缩放递归金三角。它画一个金三角,然后在里面画另一个,依此类推。这很容易,但挑战在于使其放大并围绕三角形接近的点旋转 为了让它无限放大那个点,我需要想出一个公式来计算三角形接近哪个点 此时正在运行演示: 存储库: /** * *@param{float[]}pivot *@param{float}角度 *@param{float[]}点 *@返回{float[]}点 */ 函数旋转点(枢轴、角度、点) { 常数s=数学sin(角度); 常数c=数学cos(角度); 常量p
/**
*
*@param{float[]}pivot
*@param{float}角度
*@param{float[]}点
*@返回{float[]}点
*/
函数旋转点(枢轴、角度、点)
{
常数s=数学sin(角度);
常数c=数学cos(角度);
常量pointOriginX=点[0]-轴[0];
常量pointOriginY=点[1]-轴[1];
//旋转点
常数xNew=(pointOriginX*c)-(pointOriginY*s);
常量yNew=(pointOriginX*s)+(pointOriginY*c);
常数newPoint=[
枢轴[0]+xNew,
枢轴[1]+yNew,
]
返回newPoint;
}
// https://www.onlinemath4all.com/90-degree-clockwise-rotation.html
// https://stackoverflow.com/questions/2259476/rotating-a-point-about-another-point-2d
//位置在点B和点C 72和点72之间的一半,因为AB/BC是黄金比例
函数角度(位置、高度、旋转、颜色=[0255,0255],枢轴){
//金三角72度,72度,36度
//金色侏儒36,36,108
//AB/BC是黄金比例数
// https://www.mathsisfun.com/algebra/sohcahtoa.html
常数baseLength=(数学tan(degToRad(18))*高度)*2;
常数点A=旋转点(位置,旋转,[位置[0],位置[1]-高度];//最锐角
常量点B=旋转点(位置,旋转[位置[0]-(基长/2),位置[1]);
常量点C=旋转点(位置,旋转,[位置[0]+(基长/2),位置[1]]);
drawTriangle(点A、点B、点C,[0255,0255]);
}
设i=0;
函数DrawRecursiveGoldEntryAngle(位置、高度、旋转、枢轴){
牵引角度(位置、高度、旋转[0255,0255],枢轴);
i++;
如果(i>10){
返回;
}
恒斜边长度=高度/数学cos(degToRad(18));
常数baseLength=(数学tan(degToRad(18))*高度)*2;
常数goldenRatio=斜边长度/基长;
const newHeight=高度/黄花;
const newRotation=旋转-108*Math.PI/180
const newPointC=rotatePoint(位置,旋转,[pos[0]+(baseLength/2),pos[1]]);
//从C点沿CA方向向上移动半基长度,以获得新位置
常量new斜边长度=基准长度;
常数newBaseLength=新斜边长度/黄花;
设newPosXRelative=Math.cos(newRotation)*(newBaseLength/2)
设newPosYRelative=Math.sin(newRotation)*(newBaseLength/2)
const newPos=[newPointC[0]+newPosXRelative,newPointC[1]+newposyrative];
DrawRecursiveGoldEntryAngle(新位置、新高度、新旋转[0255,0255],枢轴);
}
让三角光=高度-50;
设支点=[(宽度/2),(高度/2)-50];
设三角形位置=[宽度/2,高度/2+300];
设三角形旋转=0;
函数循环(){
i=0;
const startTime=Date.now()
wipeCanvasData();
//三角光++;
//三角旋转=三角旋转+0.005;
//drawX(枢轴点)
//drawX(三角定位)
//轴心点决定了递归函数所指向的点
//三角形旋转。应该是三角形旋转的点
//接近。
DrawRecursiveGoldEntryAngle(三角定位、三角光、三角旋转、枢轴点);
updateCanvas()
const renderTime=Date.now()-startTime
timeDelta=renderTime{
循环()
},targetFrameDuration-renderTime)
}
循环()
计算递归金三角逼近点的公式是什么?或者在这种情况下我能做些聪明的破解吗?的起点是通过起始点(a,b,c)计算的,其中a,b,c是三角形的点:
片段中的三角形不是真正的“金三角”,但计算应该是正确的
const distance=(p1,p2)=>Math.hypot(p2.x-p1.x,p2.y-p1.y);
常数交点=(p1、p2、p3、p4)=>{
常数l1A=(p2.y-p1.y)/(p2.x-p1.x);
常数l1B=p1.y-l1A*p1.x;
常数l2A=(p4.y-p3.y)/(p4.x-p3.x);
常数l2B=p3.y-l2A*p3.x;
常数x=(l2B-l1B)/(l1A-l2A);
常数y=x*l1A+l1B;
返回{x,y};
}
常数起始点=(a、b、c)=>{
常数ac=距离(a,c);
常数ab=距离(a,b);
常数bc=距离(b,c);
//余弦定律
常数alpha=Math.acos((ab*ab+ac*ac-bc*bc)/(2*ab*ac));
常数gamma=Math.acos((ac*ac+bc*bc-ab*ab)/(2*ac*bc));
常数delta=Math.PI-α/2-γ;
//正弦定律
常数cd=ac*Math.sin(α/2)/Math.sin(δ);
常数d={
x:cd*(b.x-c.x)/bc+c.x,
y:cd*(b.y-c.y)/bc+c.y
};
常数e={
x:(a.x+c.x)/2,
y:(a.y+c.y)/2
};
常数f={
x:(a.x+b.x)/2,
y:(a.y+b.y)/2,
};
返回交叉口(c、f、d、e);
};
d3.选择('svg')。追加('path'))
.attr('d','M 100,50 L150200 H 50 Z')
.style('填充','无')
.style('笔划','蓝色')
常数点=起始点({x:50,y:200},{x:100,y:50},{x:150,y:200});
控制台日志(点);
d3.选择('svg')。追加('circle'))
.attr('cx',第x点)
.attr('cy',点y)
.attr('r',5)
我想知道应该把它放在哪里。。。我想可能会有一些聪明的黑客,你可以做,你不需要拿出公式,而只是看看点最终在哪里。根据我的经验,它不够准确,从长远来看造成了太大的差异,但也许我只是做错了。我可以问同样的问题
/**
*
* @param {float[]} pivot
* @param {float} angle
* @param {float[]} point
* @returns {float[]} point
*/
function rotatePoint(pivot, angle, point)
{
const s = Math.sin(angle);
const c = Math.cos(angle);
const pointOriginX = point[0] - pivot[0];
const pointOriginY = point[1] - pivot[1];
// rotate point
const xNew = (pointOriginX * c) - (pointOriginY * s);
const yNew = (pointOriginX * s) + (pointOriginY * c);
const newPoint = [
pivot[0] + xNew,
pivot[1] + yNew,
]
return newPoint;
}
// https://www.onlinemath4all.com/90-degree-clockwise-rotation.html
// https://stackoverflow.com/questions/2259476/rotating-a-point-about-another-point-2d
// Position is half way between points B and C 72 and 72, because AB/BC is golden ratio
function drawGoldenTriangle(pos, height, rotation, color = [0,255,0,255], pivot) {
// golden triangle degrees 72, 72, 36
// golden gnomon 36, 36, 108
// AB/BC is the golden ratio number
// https://www.mathsisfun.com/algebra/sohcahtoa.html
const baseLength = (Math.tan(degToRad(18)) * height) * 2;
const pointA = rotatePoint(pos, rotation, [pos[0], pos[1] - height]); // sharpest angle
const pointB = rotatePoint(pos, rotation, [pos[0] - (baseLength / 2), pos[1]]);
const pointC = rotatePoint(pos, rotation, [pos[0] + (baseLength / 2), pos[1]]);
drawTriangle(pointA, pointB, pointC, [0,255,0,255]);
}
let i = 0;
function drawRecursiveGoldenTriangle(pos, height, rotation, pivot) {
drawGoldenTriangle(pos, height, rotation, [0,255,0,255], pivot);
i++;
if (i > 10) {
return;
}
const hypotenuseLength = height / Math.cos(degToRad(18));
const baseLength = (Math.tan(degToRad(18)) * height) * 2;
const goldenRatio = hypotenuseLength / baseLength;
const newHeight = height / goldenRatio;
const newRotation = rotation - 108 * Math.PI/180
const newPointC = rotatePoint(pos, rotation, [pos[0] + (baseLength / 2), pos[1]]);
// Go half baselength up CA direction from pointC to get new position
const newHypotenuseLength = baseLength;
const newBaseLength = newHypotenuseLength / goldenRatio;
let newPosXRelative = Math.cos(newRotation) * (newBaseLength / 2)
let newPosYRelative = Math.sin(newRotation) * (newBaseLength / 2)
const newPos = [newPointC[0] + newPosXRelative, newPointC[1] + newPosYRelative];
drawRecursiveGoldenTriangle(newPos, newHeight, newRotation, [0,255,0,255], pivot);
}
let triangleHeight = height - 50;
let pivotPoint = [(width/2),(height/2) -50];
let triangleLocation = [width/2, height/2 + 300];
let triangleRotation = 0;
function loop() {
i = 0;
const startTime = Date.now()
wipeCanvasData();
// triangleHeight++;
// triangleRotation = triangleRotation + 0.005;
// drawX(pivotPoint)
// drawX(triangleLocation)
// Pivot point determines the point which the recursive golden
// triangle rotates around. Should be the point that triangles
// approach.
drawRecursiveGoldenTriangle(triangleLocation, triangleHeight, triangleRotation, pivotPoint);
updateCanvas()
const renderTime = Date.now() - startTime
timeDelta = renderTime < targetFrameDuration ? targetFrameDuration : renderTime
this.setTimeout(() => {
loop()
}, targetFrameDuration - renderTime)
}
loop()