Javascript 计算不在一组范围之间的最小值
给定一组圆(x、y、r值),我想放置一个新点,使其具有固定/已知的y坐标(显示为水平线),并且尽可能靠近中心,但不在任何现有圆内。在示例图像中,红色的点就是结果 圆具有已知半径和Y轴属性,因此很容易计算它们在已知Y值处与水平线相交的点。效率很重要,我不想尝试一堆X坐标,并针对圆圈数组中的每个项目对它们进行测试。有没有办法从数学上计算出这个最优的X坐标?非常感谢您的帮助。顺便说一下,我正在使用Raphael.js库用javascript编写它(因为它是唯一一个支持IE8的库),但这更像是一个逻辑问题,所以语言并不重要。Javascript 计算不在一组范围之间的最小值,javascript,math,trigonometry,intervals,Javascript,Math,Trigonometry,Intervals,给定一组圆(x、y、r值),我想放置一个新点,使其具有固定/已知的y坐标(显示为水平线),并且尽可能靠近中心,但不在任何现有圆内。在示例图像中,红色的点就是结果 圆具有已知半径和Y轴属性,因此很容易计算它们在已知Y值处与水平线相交的点。效率很重要,我不想尝试一堆X坐标,并针对圆圈数组中的每个项目对它们进行测试。有没有办法从数学上计算出这个最优的X坐标?非常感谢您的帮助。顺便说一下,我正在使用Raphael.js库用javascript编写它(因为它是唯一一个支持IE8的库),但这更像是一个逻辑问
我将按如下方式处理您的问题:
基本上,圆的方程是(x-cx)2+(y-cy)2=r2。因此,通过用0替换y,可以轻松找到圆和X轴之间的交点。在这之后,你就有了一个简单的解决方法:x2-2cxx+cx2+cy2-r2=0。对于it,您有3种可能的结果:
- 无交叉-行列式将是无理数(JavaScript中为NaN),忽略此结果李>
- 一个交点-两个解决方案匹配,使用[值,值]李>
- 两个交点-两种解决方案不同,请使用[value1,value2]
var circles = [
{x:0, y:0, r:1},
{x:2.5, y:0, r:1},
{x:-1, y:0.5, r:1},
{x:2, y:-0.5, r:1},
{x:-2, y:0, r:1},
{x:10, y:10, r:1}
];
console.log(getClosestPoint(circles, 1e-10));
function getClosestPoint(circles, delta)
{
var intervals = [],
len = circles.length,
i, result;
for (i = 0; i < len; i++)
{
result = getXIntersection(circles[i])
if (result)
{
intervals.push(result);
}
}
intervals = intervals.sort(function(a, b){
return a.from - b.from;
});
if (intervals.length <= 0) return 0;
intervals = mergeIntervals(intervals, delta);
var points = getClosestPoints(intervals, delta);
points = points.sort(function(a, b){
return Math.abs(a) - Math.abs(b);
});
return points[0];
}
function getXIntersection(circle)
{
var d = Math.sqrt(circle.r * circle.r - circle.y * circle.y);
return isNaN(d) ? null : {from: circle.x - d, to: circle.x + d};
}
function mergeIntervals(intervals, delta)
{
var curr = intervals[0],
result = [],
len = intervals.length, i;
for (i = 1 ; i < len ; i++)
{
if (intervals[i].from <= curr.to + delta)
{
curr.to = Math.max(curr.to, intervals[i].to);
} else {
result.push(curr);
curr = intervals[i];
}
}
result.push(curr);
return result;
}
function getClosestPoints(intervals, delta)
{
var result = [],
len = intervals.length, i;
for (i = 0 ; i < len ; i++)
{
result.push( intervals[i].from - delta );
result.push( intervals[i].to + delta );
}
return result;
}
var圆=[
{x:0,y:0,r:1},
{x:2.5,y:0,r:1},
{x:-1,y:0.5,r:1},
{x:2,y:-0.5,r:1},
{x:-2,y:0,r:1},
{x:10,y:10,r:1}
];
console.log(getClosestPoint(圆圈,1e-10));
函数GetClosesPoint(圆、三角形)
{
var区间=[],
len=圆。长度,
i、 结果;
对于(i=0;i 如果(左图中的interval.length,为什么红点不在第四个圆的两个交点之一(从左边算起)?在我看来,这些点比指示点更靠近右圆的中心。或者“中心”是指其他东西吗?如果是,什么?对不起-我指的是图表中的垂直线(为了简单起见,将其视为X=0)你说的“尝试一堆X坐标”是什么意思?您只需尝试交叉点。+1用于折叠间隔,这似乎是OP没有想到的。顺便说一句,您可以在计算所有交叉点的过程中检查任何间隔是否包括中心,甚至在对它们进行排序之前。@Bergi-关于边走边跟踪哪个间隔(如果有的话)的极好观点包含中心。由于合并,最多只能有一个这样的间隔。谢谢Ted,这看起来很有希望&明天将在JS中尝试。请原谅我的无知,但当您提到“一组间隔”时,您是指一个Xstart和Xend值数组(即沿x轴的范围)吗?通过“折叠Ic…”你的意思是,例如,如果一个是1delta
是否合适(实际上,扩大间隔)也不清楚