Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/458.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 递归金三角,三角形接近哪一点?_Javascript_Recursion_Math_Html5 Canvas_Trigonometry - Fatal编程技术网

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)计算的,其中abc是三角形的点:

片段中的三角形不是真正的“金三角”,但计算应该是正确的

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()