请参阅此jsFiddle帖子了解有效的弧线图;感谢Simon Sarris在我之前的问题中提供的解决方法。
我正在使用KineticJS插件来创建形状并使用事件处理程序。假设你点击弧上的某个地方并且弧知道你点击的位置(x
,y
),那么这2个坐标如何用于确定百分比?
单击任意位置时,总百分比始终为100%。
外接
为了简化这一点,我可以做些什么(x
,y
)虚拟弯曲对象,以便x
从0变为最大x
?< / p>
答案 0 :(得分:2)
简单的三角学。 sin(angle) = opposite / adjacent
。 opposite
是y
值,adjacent
是x
值。所以Math.asin((xx - x) / (yy - y))
其中xx和yy是弧心的坐标。这将为您提供角度,然后您可以将2 * Math.PI
除以。
我不记得负面数字会发生什么。您可能必须获取参数的Math.abs
值,然后计算出点击所在的象限(使用<
和>
轻松完成)并添加Math.PI / 2
对于每一个。
答案 1 :(得分:1)
这包括检查鼠标是否在弧内:
// Return range is 0 to Math.PI * 2
function get_mouse_circle_angle(origin_x, origin_y, mouse_x, mouse_y) {
var mouse_angle = Math.atan2(mouse_y - origin_y, mouse_x - origin_x);
if (mouse_angle < 0) {
mouse_angle = (Math.PI * 2) + mouse_angle;
}
return mouse_angle;
}
// Return range is [0, 1)
// 0/1 is 3 oclock
function get_mouse_circle_percent(origin_x, origin_y, mouse_x, mouse_y) {
var mouse_angle = get_mouse_circle_angle(origin_x, origin_y, mouse_x, mouse_y);
return mouse_angle / (2 * Math.PI);
}
function get_mouse_arc_pos(origin_x, origin_y, mouse_x, mouse_y, radius, thickness) {
var mouse_angle = Math.atan2(mouse_y - origin_y, mouse_x - origin_x);
if (mouse_angle < 0) {
mouse_angle = (Math.PI * 2) + mouse_angle;
}
var mouse_percent = mouse_angle / (2 * Math.PI);
var circle_edge_x = origin_x + (radius + thickness / 2) * Math.cos(mouse_angle);
var circle_edge_y = origin_y + (radius + thickness / 2) * Math.sin(mouse_angle);
var arc_inside_x = origin_x + (radius - thickness / 2) * Math.cos(mouse_angle);
var arc_inside_y = origin_y + (radius - thickness / 2) * Math.sin(mouse_angle);
var is_in_circle = true;
if (mouse_angle <= (2 * Math.PI) * 0.25) {
if (mouse_x > circle_edge_x || mouse_y > circle_edge_y)
is_in_circle = false;
}
else if (mouse_angle <= (2 * Math.PI) * 0.5) {
if (mouse_x < circle_edge_x || mouse_y > circle_edge_y)
is_in_circle = false;
}
else if (mouse_angle <= (2 * Math.PI) * 0.75) {
if (mouse_x < circle_edge_x || mouse_y < circle_edge_y)
is_in_circle = false;
}
else {
if (mouse_x > circle_edge_x || mouse_y < circle_edge_y)
is_in_circle = false;
}
var is_in_arc = is_in_circle;
if (is_in_circle) {
if (mouse_angle <= (2 * Math.PI) * 0.25) {
if (mouse_x < arc_inside_x || mouse_y < arc_inside_y)
is_in_arc = false;
}
else if (mouse_angle <= (2 * Math.PI) * 0.5) {
if (mouse_x > arc_inside_x || mouse_y < arc_inside_y)
is_in_arc = false;
}
else if (mouse_angle <= (2 * Math.PI) * 0.75) {
if (mouse_x > arc_inside_x || mouse_y > arc_inside_y)
is_in_arc = false;
}
else {
if (mouse_x < arc_inside_x || mouse_y > arc_inside_y)
is_in_arc = false;
}
}
return {
angle: mouse_angle,
percent: mouse_percent,
is_in_circle: is_in_circle,
is_in_arc: is_in_arc
};
}
答案 2 :(得分:0)
没有真正测试过,但从技术上讲,它应该可以运行:
// Where x1 and y1 should be the coordinates of the arc's center
function angle(x1, y1, x2, y2) {
// Calculate a · b
var nominator = x1 * x2 + y1 * y2;
// Calculate ||a|| ||b||
var denominator = Math.sqrt(x1*x1 + y1*y1) * Math.sqrt(x2*x2 + y2*y2);
if (denominator == 0) return 0; // Indifinite angle
// Return the angle
return Math.acos(nominator / denominator);
}
// Returns a percent, might be negative
var percent = angle(0, 0, mouseX, mouseY) / (2*Math.PI);
对于负数,您可以尝试添加1,因为它在[-1,1]范围内
if (percent < 0) percent += 1;