refer :
https://www.youtube.com/watch?v=R7dObDtw1aA
https://www.shuxuele.com/algebra/trig-finding-angle-right-triangle.html
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan
https://www.rapidtables.com/convert/number/how-radians-to-degrees.html
1. coordinate 和 css translate 是不同的东西
数学有 coordinate x,y ,
左上是 ( -x, +y )
右上是 ( +x, +y)
左下是 ( -x, -y)
右下是 ( +x, -y)
css translate 是说移动的方向.
+x 是往右
-x 是往左
+y 是往下
-y 是往上
注意 : coordinate y 和 translate y 是相反的.
2. 三角形和 tan sin cos
tan sin cos 在 js 里是 Math.cos, Math.sin, Math.tan
反向是 Math.acos, Math.asin, Math.atan
一般上我们 cos(degree) 使用的是 degree, 但是 js 使用的是 radian
所以要背一个转换的公式
radian = degree * Math.PI / 180;
export function degreeToRadian(degree: number): number { return degree * Math.PI / 180; } export function radianToDegree(radian: number): number { return radian * 180 / Math.PI; }
求三角形斜线的长度是
export function calcRadius(width: number, height: number): number { return Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); }
求 x, y coordinate 当拥有 degree 和 radius (斜线的长度)
cos(deg) = x / radius
sin(deg) = y / radius
export function calcCoordinate(radius: number, degree: number): Xy { return { x: Math.cos(degreeToRadian(degree)) * radius, y: Math.sin(degreeToRadian(degree)) * radius } }
求 degree 当有 x, y
单靠反推上面求 x,y 的公式,我们是无法获取 degree 的,因为 cos(135) === cos(225).
所以更好的做法是通过 tan
tan(d) = y / x
有一点要特别注意就是, x y 的正负值, 代表了它在不同区域. 这个是会直接影响 degree 的. 我们要特别处理.
export function calcDegree(coordinate: Xy): number { const { x, y } = coordinate; const result = radianToDegree(Math.atan(y / x)); if (x < 0 && y >= 0) { return 180 - Math.abs(result); // 这里 result 是 negative } else if (x < 0 && y < 0) { return 180 + result; // 这里 result 是 positive } else if (x >= 0 && y < 0) { return 360 - Math.abs(result) // 这里 result 是 negative } else { return result; // 这里 result 是 positive } }
最后是 js 的另一个函数来做到上面一样的效果. Math.atan2(y, x)
export function calcDegree(coordinate: Xy): number { // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2 const result = radianToDegree(Math.atan2(coordinate.y, coordinate.x)); return (result > 0) ? result : 360 - Math.abs(result); }
css 的 rotate 和我们数学的方向也是不太一样的, 数学我们是 右边线开始,逆时针旋转 20 degree 是这样的. 上面的算法全部基于这个概念
所以如果我想说下面这个 x, y 顺势旋转 20 degree 算法应该是..
export function calcCoordinateAfterRotate(currentCoordinate: Xy, rotateDegree: number): Xy { const radius = calcRadius(Math.abs(currentCoordinate.x), Math.abs(currentCoordinate.y)); const degree = calcDegree(currentCoordinate); const degreeAfterRotate = degree - rotateDegree; return calcCoordinate(radius, degreeAfterRotate); }
换算 coordinate 去 translate x, y
export function calcTranslate(fromCoordinate: Xy, toCoordinate: Xy): Xy { return { x: toCoordinate.x - fromCoordinate.x, y: fromCoordinate.y - toCoordinate.y } }
原文:https://www.cnblogs.com/keatkeat/p/10389742.html