Calculate minimum value not between multiple ranges

Given an array of circles (x, y, r values), I want to place a new point so that it has a fixed / known Y-coordinate (shown as a horizontal line) and as close to the center as possible, but not in any of the existing circles. In the sample images, the result will be red.

Circles have a known radius and attribute of the Y axis, so it’s easy to calculate the points where they intersect a horizontal line with a known Y value. Efficiency is important, I don’t want to try a bunch of X-coordinates and check them all against each element of the circle array. Is there any way to mathematically solve this optimal X coordinate? Any help is greatly appreciated. By the way, I write it in javascript using the Raphael.js library (because it is the only one supporting IE8), but this is more of a logical problem, so the language does not really matter. enter image description here

+4
source share
3 answers

(x - c x) 2 + (y - c y) 2= r 2. X, y 0. : x 2 - 2c x x + c x 2 + c y 2 - r 2= 0. 3 :

  • - (NaN JavaScript), ;
  • - , [, ];
  • - , [value1, value2].

, , . , , .

, x, / / . , , , , .

O (n log n), . 1 * 10 -10 delta:

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;
}
+1

:

  • S, X ,
  • c c of c X. c , . , c () S ( , S ); , S, c ' c I' c S. , c S.
  • , S ( , , S ). , , ; , .
+2
  • intersect_segments ( x = 0 y = 0)

  • intersectsegments upperlimit < 0

  • point1 = 0 segment = 0

  • 1 intersectsegment [segment]

    4,1. point1 []

    4,2.

  • sort intersectsegments by lowerlimit loerlimit > 0

  • point2 = 0 segment = 0

  • 2 intersectsegments [segment]

    7.1. 2

    7,2.

  • - p1 p2

0
source

All Articles