Vit*_*.us 22 javascript css math geometry css3
我有4个点1,2,3,4封闭的矩形.
这些点以下列方式位于数组中: x1 y1 x2 y2 x3 y3 x4 y4
我遇到的问题是矩形可以以一定角度旋转.
如何计算原始点(灰色轮廓)和角度?

我试图在javascript + css3-transform中重现这个效果,所以我需要首先知道直尺寸,然后用css旋转.
我只是通过比较点来知道矩形是否笔直 y1==y2
if(x1==x4 && x2==x3 && y1==y2 && y4==y3){
rectangle.style.top = y1;
rectangle.style.left = x1;
rectangle.style.width = x2-x1;
rectangle.style.height = y4-y1;
rectangle.style.transform = "rotate(?deg)";
}
Run Code Online (Sandbox Code Playgroud)
Rob*_*obG 19
您可以使用同一侧的任何坐标对来计算旋转角度.请注意,数学角度通常假定为+ ve X轴长0,逆时针旋转增加(因此沿+ ve Y轴为90°,-ve X轴为180°,依此类推).
此外,javascript三角函数返回弧度值,必须在用于CSS变换之前转换为度.
如果形状旋转不超过90°,那么寿命相当简单,您可以使用直角三角形的tanget比率:
tan(angle) = length of opposite side / length of adjacent side
Run Code Online (Sandbox Code Playgroud)
对于OP,最好使用的角是1和4,以便旋转保持在第一象限和顺时针(根据草案CSS3规范).在javascript术语中:
var rotationRadians = Math.atan((x1 - x4) / (y1 - y4));
Run Code Online (Sandbox Code Playgroud)
要转换为学位:
var RAD2DEG = 180 / Math.PI;
var rotationDegrees = rotationRadians * RAD2DEG;
Run Code Online (Sandbox Code Playgroud)
如果旋转角度大于90°,则需要调整角度.例如,当角度大于90°但小于180°时,您将获得上述结果并需要增加180°:
rotationDegrees += 180;
Run Code Online (Sandbox Code Playgroud)
此外,如果您正在使用页面维度,则y坐标会在页面下方增加,这与正常的数学意义相反,因此您需要扭转上述的意义y1 - y4.
基于OP中的点的方向,以下是以度为单位返回矩形的中心和顺时针旋转的一般函数.这就是你应该需要的,尽管如果你愿意,你可以自己将角落旋转到"水平".您可以应用三角函数来计算新角点或只做一些平均值(类似于Ian的答案).
/* General case solution for a rectangle
*
* Given coordinages of [x1, y1, x2, y2, x3, y3, x4, y4]
* where the corners are:
* top left : x1, y1
* top right : x2, y2
* bottom right: x3, y3
* bottom left : x4, y4
*
* The centre is the average top left and bottom right coords:
* center: (x1 + x3) / 2 and (y1 + y3) / 2
*
* Clockwise rotation: Math.atan((x1 - x4)/(y1 - y4)) with
* adjustment for the quadrant the angle is in.
*
* Note that if using page coordinates, y is +ve down the page which
* is the reverse of the mathematic sense so y page coordinages
* should be multiplied by -1 before being given to the function.
* (e.g. a page y of 400 should be -400).
*/
function getRotation(coords) {
// Get center as average of top left and bottom right
var center = [(coords[0] + coords[4]) / 2,
(coords[1] + coords[5]) / 2];
// Get differences top left minus bottom left
var diffs = [coords[0] - coords[6], coords[1] - coords[7]];
// Get rotation in degrees
var rotation = Math.atan(diffs[0]/diffs[1]) * 180 / Math.PI;
// Adjust for 2nd & 3rd quadrants, i.e. diff y is -ve.
if (diffs[1] < 0) {
rotation += 180;
// Adjust for 4th quadrant
// i.e. diff x is -ve, diff y is +ve
} else if (diffs[0] < 0) {
rotation += 360;
}
// return array of [[centerX, centerY], rotation];
return [center, rotation];
}
Run Code Online (Sandbox Code Playgroud)
矩形的中心位于两个相对的角之间:
cx = (x1 + x3) / 2
cy = (y1 + y3) / 2
Run Code Online (Sandbox Code Playgroud)
矩形的大小是两点之间的距离:
w = sqrt(pow(x2-x1, 2) + pow(y2-y1, 2))
h = sqrt(pow(x3-x2, 2) + pow(y3-y2, 2))
Run Code Online (Sandbox Code Playgroud)
灰色矩形的角可以从中心和大小计算,例如左上角:
x = cx - w / 2
y = cy - h / 2
Run Code Online (Sandbox Code Playgroud)
角度是正方形一侧的反正切:
a = arctan2(y4 - y1, x4 - x1)
Run Code Online (Sandbox Code Playgroud)
(我不确定它返回的确切角度,或者你对这个问题的预期角度,所以你可以稍微测试一下.)