提高JS中的trig计算精度
Improve trig calculation precision in JS
我有一个 JS 图形的代码,它应该绘制三个圆,无论它们的半径是多少,它们的边缘应该总是接触。
import React, { useState, useEffect } from "react";
import "./styles.css";
export default function App() {
//circles[0] = r1
//circles[1] = r2
//circles[2] = r3
const circles = [40, 30, 20];
const colours = ["green", "blue", "red"];
let circle2xPos =
2 * Math.sqrt(circles[0] * circles[1]) + circles[0]; // What Dr E has
let r1r2 = circles[0] + circles[1];
let r1r3 = circles[0] + circles[2];
let r2r3 = circles[1] + circles[2];
let newAngle = Math.atan2(r1r2,r1r3)
let ycoord = Math.cos(newAngle) * r1r3
let xcoord = Math.sin(newAngle) * r1r2 + circles[0]
const getCircleY = index => {
let yPos = 0;
if (index === 2) {
yPos = h
}
return yPos;
};
const getCircleX = (index, x) => {
let xPos = 0;
console.log(circles);
for (let i = 0; i < index + 1; i++) {
console.log(circles[i]);
if (i === 0) {
xPos = circles[1];
} else if (i === 1) {
xPos = circle2xPos;
console.log("xPos", xPos);
} else if (i === 2) {
xPos = xcoord + circles[0]
}
}
return xPos;
};
const getCircles = () => {
return circles.map((item, index) => (
<div
className="circle"
style={{
position: "absolute",
top: getCircleY(index),
left: getCircleX(index, getCircleY(index)),
height: 2 * item,
width: 2 * item,
padding: 0,
margin: 0,
backgroundColor: colours[index],
borderRadius: "50%"
}}
/>
));
};
return (
<div className="App">
<div className="circles">{getCircles()}</div>
</div>
);
}
有点像 - 前两个总是接触,但下一个圆圈有时只会在正确的位置结束。
我尝试了很多不同的方法来计算第三个圆的坐标,我总是设法找到特定值的解决方案,但我似乎无法概括,所以它适用于任何数字?它似乎不只是将 cos 或 sin 保持在 1 和 -1 之间,所以 arc 函数不 return NaN,有时 trig 值似乎不正确并且第三个圆圈在错误的位置。
对于第二个圆,最好从 (x,y) = (r1, 2r1+r3) 开始(半径直接与 y 轴成一直线,因此圆 2 的死点堆叠在圆的顶部1), 然后围绕圆 1 的中心旋转圆 2,直到它与圆 3 的边缘相交 - 我该怎么做?
在你的 circles 数组中,你有 40,30, 20。在它下面,你有 r1r2 = circle[0] + circles[1] 所以这些看起来是半径,对吗?
假设以上是正确的,正确的做法是:
起点1在原点(0,0)(以后可以平移所有点),起点2在x轴(r1 + r2, 0)
Pt3 与 Pt1 的距离为 r1 + r2,并且应成 atan(r2+ r1/r3 + r1) 角,或者只是 atan2(r2 + r1,r3 + r1);
我认为应该可行
我有一个 JS 图形的代码,它应该绘制三个圆,无论它们的半径是多少,它们的边缘应该总是接触。
import React, { useState, useEffect } from "react";
import "./styles.css";
export default function App() {
//circles[0] = r1
//circles[1] = r2
//circles[2] = r3
const circles = [40, 30, 20];
const colours = ["green", "blue", "red"];
let circle2xPos =
2 * Math.sqrt(circles[0] * circles[1]) + circles[0]; // What Dr E has
let r1r2 = circles[0] + circles[1];
let r1r3 = circles[0] + circles[2];
let r2r3 = circles[1] + circles[2];
let newAngle = Math.atan2(r1r2,r1r3)
let ycoord = Math.cos(newAngle) * r1r3
let xcoord = Math.sin(newAngle) * r1r2 + circles[0]
const getCircleY = index => {
let yPos = 0;
if (index === 2) {
yPos = h
}
return yPos;
};
const getCircleX = (index, x) => {
let xPos = 0;
console.log(circles);
for (let i = 0; i < index + 1; i++) {
console.log(circles[i]);
if (i === 0) {
xPos = circles[1];
} else if (i === 1) {
xPos = circle2xPos;
console.log("xPos", xPos);
} else if (i === 2) {
xPos = xcoord + circles[0]
}
}
return xPos;
};
const getCircles = () => {
return circles.map((item, index) => (
<div
className="circle"
style={{
position: "absolute",
top: getCircleY(index),
left: getCircleX(index, getCircleY(index)),
height: 2 * item,
width: 2 * item,
padding: 0,
margin: 0,
backgroundColor: colours[index],
borderRadius: "50%"
}}
/>
));
};
return (
<div className="App">
<div className="circles">{getCircles()}</div>
</div>
);
}
有点像 - 前两个总是接触,但下一个圆圈有时只会在正确的位置结束。
我尝试了很多不同的方法来计算第三个圆的坐标,我总是设法找到特定值的解决方案,但我似乎无法概括,所以它适用于任何数字?它似乎不只是将 cos 或 sin 保持在 1 和 -1 之间,所以 arc 函数不 return NaN,有时 trig 值似乎不正确并且第三个圆圈在错误的位置。
对于第二个圆,最好从 (x,y) = (r1, 2r1+r3) 开始(半径直接与 y 轴成一直线,因此圆 2 的死点堆叠在圆的顶部1), 然后围绕圆 1 的中心旋转圆 2,直到它与圆 3 的边缘相交 - 我该怎么做?
在你的 circles 数组中,你有 40,30, 20。在它下面,你有 r1r2 = circle[0] + circles[1] 所以这些看起来是半径,对吗?
假设以上是正确的,正确的做法是:
起点1在原点(0,0)(以后可以平移所有点),起点2在x轴(r1 + r2, 0)
Pt3 与 Pt1 的距离为 r1 + r2,并且应成 atan(r2+ r1/r3 + r1) 角,或者只是 atan2(r2 + r1,r3 + r1);
我认为应该可行