160 lines
3.5 KiB
Java
160 lines
3.5 KiB
Java
![]() |
var Util = require('../../util/index');
|
||
|
|
||
|
function circlePoint(cx, cy, r, angle) {
|
||
|
return {
|
||
|
x: Math.cos(angle) * r + cx,
|
||
|
y: Math.sin(angle) * r + cy
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function angleNearTo(angle, min, max, out) {
|
||
|
var v1;
|
||
|
var v2;
|
||
|
|
||
|
if (out) {
|
||
|
if (angle < min) {
|
||
|
v1 = min - angle;
|
||
|
v2 = Math.PI * 2 - max + angle;
|
||
|
} else if (angle > max) {
|
||
|
v1 = Math.PI * 2 - angle + min;
|
||
|
v2 = angle - max;
|
||
|
}
|
||
|
} else {
|
||
|
v1 = angle - min;
|
||
|
v2 = max - angle;
|
||
|
}
|
||
|
|
||
|
return v1 > v2 ? max : min;
|
||
|
}
|
||
|
|
||
|
function nearAngle(angle, startAngle, endAngle, clockwise) {
|
||
|
var plus = 0;
|
||
|
|
||
|
if (endAngle - startAngle >= Math.PI * 2) {
|
||
|
plus = Math.PI * 2;
|
||
|
}
|
||
|
|
||
|
startAngle = Util.mod(startAngle, Math.PI * 2);
|
||
|
endAngle = Util.mod(endAngle, Math.PI * 2) + plus;
|
||
|
angle = Util.mod(angle, Math.PI * 2);
|
||
|
|
||
|
if (clockwise) {
|
||
|
if (startAngle >= endAngle) {
|
||
|
if (angle > endAngle && angle < startAngle) {
|
||
|
return angle;
|
||
|
}
|
||
|
|
||
|
return angleNearTo(angle, endAngle, startAngle, true);
|
||
|
}
|
||
|
|
||
|
if (angle < startAngle || angle > endAngle) {
|
||
|
return angle;
|
||
|
}
|
||
|
|
||
|
return angleNearTo(angle, startAngle, endAngle);
|
||
|
}
|
||
|
|
||
|
if (startAngle <= endAngle) {
|
||
|
if (startAngle < angle && angle < endAngle) {
|
||
|
return angle;
|
||
|
}
|
||
|
|
||
|
return angleNearTo(angle, startAngle, endAngle, true);
|
||
|
}
|
||
|
|
||
|
if (angle > startAngle || angle < endAngle) {
|
||
|
return angle;
|
||
|
}
|
||
|
|
||
|
return angleNearTo(angle, endAngle, startAngle);
|
||
|
}
|
||
|
|
||
|
function arcProjectPoint(cx, cy, r, startAngle, endAngle, clockwise, x, y, out) {
|
||
|
var v = [x, y];
|
||
|
var v0 = [cx, cy];
|
||
|
var v1 = [1, 0];
|
||
|
var subv = Util.vec2.subtract([], v, v0);
|
||
|
var angle = Util.vec2.angleTo(v1, subv);
|
||
|
angle = nearAngle(angle, startAngle, endAngle, clockwise);
|
||
|
var vpoint = [r * Math.cos(angle) + cx, r * Math.sin(angle) + cy];
|
||
|
|
||
|
if (out) {
|
||
|
out.x = vpoint[0];
|
||
|
out.y = vpoint[1];
|
||
|
}
|
||
|
|
||
|
var d = Util.vec2.distance(vpoint, v);
|
||
|
return d;
|
||
|
}
|
||
|
|
||
|
function arcBox(cx, cy, r, startAngle, endAngle, clockwise) {
|
||
|
var angleRight = 0;
|
||
|
var angleBottom = Math.PI / 2;
|
||
|
var angleLeft = Math.PI;
|
||
|
var angleTop = Math.PI * 3 / 2;
|
||
|
var points = [];
|
||
|
var angle = nearAngle(angleRight, startAngle, endAngle, clockwise);
|
||
|
|
||
|
if (angle === angleRight) {
|
||
|
points.push(circlePoint(cx, cy, r, angleRight));
|
||
|
}
|
||
|
|
||
|
angle = nearAngle(angleBottom, startAngle, endAngle, clockwise);
|
||
|
|
||
|
if (angle === angleBottom) {
|
||
|
points.push(circlePoint(cx, cy, r, angleBottom));
|
||
|
}
|
||
|
|
||
|
angle = nearAngle(angleLeft, startAngle, endAngle, clockwise);
|
||
|
|
||
|
if (angle === angleLeft) {
|
||
|
points.push(circlePoint(cx, cy, r, angleLeft));
|
||
|
}
|
||
|
|
||
|
angle = nearAngle(angleTop, startAngle, endAngle, clockwise);
|
||
|
|
||
|
if (angle === angleTop) {
|
||
|
points.push(circlePoint(cx, cy, r, angleTop));
|
||
|
}
|
||
|
|
||
|
points.push(circlePoint(cx, cy, r, startAngle));
|
||
|
points.push(circlePoint(cx, cy, r, endAngle));
|
||
|
var minX = Infinity;
|
||
|
var maxX = -Infinity;
|
||
|
var minY = Infinity;
|
||
|
var maxY = -Infinity;
|
||
|
Util.each(points, function (point) {
|
||
|
if (minX > point.x) {
|
||
|
minX = point.x;
|
||
|
}
|
||
|
|
||
|
if (maxX < point.x) {
|
||
|
maxX = point.x;
|
||
|
}
|
||
|
|
||
|
if (minY > point.y) {
|
||
|
minY = point.y;
|
||
|
}
|
||
|
|
||
|
if (maxY < point.y) {
|
||
|
maxY = point.y;
|
||
|
}
|
||
|
});
|
||
|
return {
|
||
|
minX: minX,
|
||
|
minY: minY,
|
||
|
maxX: maxX,
|
||
|
maxY: maxY
|
||
|
};
|
||
|
}
|
||
|
|
||
|
module.exports = {
|
||
|
nearAngle: nearAngle,
|
||
|
projectPoint: function projectPoint(cx, cy, r, startAngle, endAngle, clockwise, x, y) {
|
||
|
var rst = {};
|
||
|
arcProjectPoint(cx, cy, r, startAngle, endAngle, clockwise, x, y, rst);
|
||
|
return rst;
|
||
|
},
|
||
|
pointDistance: arcProjectPoint,
|
||
|
box: arcBox
|
||
|
};
|