【问题标题】:Improve trig calculation precision in JS提高 JS 中的 trig 计算精度
【发布时间】:2020-10-16 15:29:35
【问题描述】:

我有一个 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 函数不会返回 NaN,有时 trig 值似乎关闭并且第三个圆圈位于错误的位置。

对于第二个圆,最好从 (x,y) = (r1, 2r1+r3) 开始(半径直接与 y 轴对齐,因此圆 2 的死点堆叠在圆 1 的顶部) ,然后围绕圆 1 的中心旋转圆 2,直到它遇到圆 3 的边缘 - 我该怎么做?

【问题讨论】:

  • 你有没有考虑到定位是从左上角而不是圆心开始的? (由于在 DOM 中

标签: javascript reactjs math.js


【解决方案1】:

在您的圆数组中,您有 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);

我相信这应该可行

【讨论】:

  • 如果我理解正确(对不起) let newAngle = Math.atan2(r1r2,r1r3) let ycoord = newAngle * r1r3 let xcoord = (newAngle * r1r2) + circles[0]
  • 几乎。为了找到坐标,而不是 newAngle * ... 你需要使用 cos(newAngle) 和 sin(newAngle)
  • 它有点工作 - 奇怪的是它不能完全工作?是因为三角函数的精度吗?
  • @Davtho1983 这可能是三角函数的精度。但我认为这更有可能是因为你在某个地方四舍五入。
猜你喜欢
  • 1970-01-01
  • 2014-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多