Знайдіть найближче найкраще для кола


12

Нижче наведено приклад зображення, якщо у мене є точка білої точки в середині і я хочу знайти найближче можливе місце для синього кола (що, очевидно, в тому місці, де я розмістив його), якщо всі червоні кола вже існують . Як я можу знайти це місце?

Продуктивність для мене не є основною проблемою для цієї програми.

введіть тут опис зображення


1
яке значення чорного кола? чи можете ви розмістити над ним синє коло?
Еван

2
Отже, щоб було зрозуміло, ви хочете розташувати синє коло таким чином, щоб воно було якомога коротшим від відстані від білої точки, не перекриваючи жодне з інших кіл?
Роберт Харві


2
Чи завжди всі кола торкаються якогось іншого кола хоча б в одному місці?
Роберт Харві

Відповіді:


4

Це не є загальним рішенням, оскільки існує кілька ситуацій, якщо воно не забезпечить положення синього кола з найкоротшою відстані до білої точки. Наприклад, якщо у вас є 100 червоних кульок, згрупованих разом, і біла крапка далеко від цієї групи червоних кульок, жодна з червоних куль не матиме жодного впливу на положення синього кола, яке може бути просто зосереджено на білій крапці . Також не буде показано всі деталі розрахунків. У будь-якому випадку для підмножини конфігурацій, де рішення (синє коло) є дотичним до двох червоних кіл, має працювати наступне:
1) нехай R - радіус синього кола
2) зробіть цикл над усіма парами червоних кіл, так Я знаю, що це O (n2).
3) для кожної пари кружків i, j з центрами в (xi, yi) і (xj, yj) з відповідними радіусами ri і rj, обчисліть квадрат відстані між парою кіл

d_ij^2=(xi-xj)^2+(yi-yj)^2  

4) поставте всі пари кіл, які

dij^2<R^2

у список.

5) пройдіть список, знайшовши 2 розв’язання кіл радіуса R, дотичних до обох кіл i та j. Для цього використовуйте ці рівняння разом із цим зображенням два кандидати синього кола для пари червоних кіл

a = R+ri  
b = R+rj  
c = dij  
α = arccos((b^2+c^2-a^2)/(2bc)  

З вищенаведеною інформацією ви можете знайти (X1ij, Y1ij) та (X2ij, Y2ij) центри двох дотичних до кіл i та j кіл. Для кожного кандидата блакитний круг обведіть над усіма іншими червоними колами та подивіться, чи не перетинаються вони. Якщо вони відкидають це, якщо не перевіряють відстань до білого кола. Якщо ви будете тримати цю відстань на меншій відстані, я думаю, ви знайдете рішення, коли закінчите переглядати список пар кіл. Алгоритм здається O (n3).


не працює, коли є лише одне коло
Еван

або два кола, але з цільовою точкою поза ними обох
Еван

проблема полягає в тому, що ви не можете бути впевнені, що у вас є всі крайні справи
Еван

також. Є унікальні рішення для цих випадків
Еван

Потрібно записати всі припущення, згідно з якими рішення є правильним або хоча б вказати на всі прикордонні випадки. Деякі з них можуть бути очевидними, але деякі - ні. Наприклад, це не спрацює, якщо можна намалювати лінію, яка відокремлює білу крапку від усіх червоних кіл, а біла крапка менша за R від найближчого кола.
Влад

2

Найближче розташування до точки буде або на точці, або дотику до кола.

тому спочатку перевірте крапку, потім оберніть нове коло навколо краю кожного наявного кола, обчисливши відстань від точки і якщо ви перекриваєтесь під час проходження та стежите за точкою мінімальної відстані. Зупиніться, коли ви пройшли кожне коло.

тобто. перевірити всі точки на зелених лініях, плюс біле коло. де зелена лінія - це коло з радіусом червоного плюс синього

можливі центральні точки

вам потрібно перевірити всю зелену лінію, а не лише перехрестя, щоб ви покривали ці крайові корпуси.

випадки одного кола

Очевидно, що крок розміру вашого обходу буде важливим з точки зору продуктивності. Але оскільки ви заявляєте, що ефективність не є проблемою, виберіть значення, що відповідає роздільній здатності вихідного значення. тобто плавати, довго?

уточнення:

моя пропозиція полягає в тому, щоб змусити всі точки навколо кожного кола тестувати на збіг з усіма іншими колами в кожній точці. ніякої кмітливості.

Якщо приклад pic вказує на кількість кіл та роздільну здатність, це не повинно бути проблемою для стандартного ПК

маємо 20 кіл середнього радіуса 200, так що приблизно 20 * 2 π * 200 балів * 20 тестів перетину = 4800000 ітерацій

Примітка:

Такі ітеративні підходи недосконалі в тому, що ваш розмір кроків, в даному випадку роздільна здатність вашого результату, може сильно вплинути на результат.

Скажіть, у мене є два червоних кола на відстані 2 пікселі та синє коло з радіусом 1 пікселя. Очевидно, що один із двох пікселів як центр синього кола перекриє один із червоних. але, очевидно, є місце для кола, якщо центр лежить між двома пікселями.

Звідси мій коментар із запитанням про дозвіл результату. про які ви сказали, може бути чим завгодно.

Ви також можете вирішити одночасне рівняння для кожної пари кіл із збільшенням радіуса на радіус синього кола.

це дасть вам точки, коли синє коло буде чіткіше торкатися обох червоних кіл, ніж повторювати.

Однак. є кілька умов, коли, якщо ви це робите, ви отримуєте неправильну чи відсутність відповіді. тобто.

1 або без кіл

2 або більше кіл, але з цільовою точкою далеко та поза ними.

багато кіл, але з цільовою точкою близько до поверхні


2
Те, що йому потрібно прокрутити край синього кола навколо зовнішньої частини інших кіл, - це легко зрозуміти. Важкою частиною є з'ясування рівнянь / розрахунків для цього.
Роберт Харві

1
справді? його справедливий (x-x1) ^ 2 + (y-y1) ^ 2 = (r + r1) ^ 2
Еван

2
І тоді вам доведеться все це зробити ще раз, коли ви спробуєте наступний пункт. Я знаю, що ОП заявила, що продуктивність не викликає занепокоєння, але вона повинна завершитись до теплової смерті Всесвіту.
Роберт Харві

2
Єдиний спосіб дізнатися, чи отримаєте ви десять оновлень, - це опублікувати свій C # код і подивитися, що відбувається.
Роберт Харві

2
що я думаю, що станеться, це те, що ОП зафіксує це як відповідь на домашнє завдання, і ми його більше ніколи не почуємо
Еван

1

Цей планк містить робочий код,

Концепція

Дані кола - це C1, C2 .... Cn

і координати кола Cn - Cnx, Cny і радіус Cr

а радіус необхідного кола дорівнює R

якщо синє коло знаходиться в X, Y місці, і якщо воно не суперечить жодним іншим колам, істинні наступні рівняння

(C1x - X)^2 + (C1y - Y)^2 > (C1r + R)^2
(C2x - X)^2 + (C2y - Y)^2 > (C2r + R)^2
....
(Cnx - X)^2 + (Cny - Y)^2 > (Cnr + R)^2

зміна першого рівняння,

C1x^2 - 2C1x*X + X^2 + C1y^2 - 2C1y*Y + Y^2 > C1r^2 + 2C1r*R + R^2
X^2 + Y^2 - 2C1x*X - 2C1y*Y > C1r^2 + 2C1r*R + R^2 - C1x^2 - C1y^2

тому рівняння можуть переписувати як,

X^2 + Y^2 - 2C1x*X - 2C1y*Y > C1r^2 + 2C1r*R + R^2 - C1x^2 - C1y^2
X^2 + Y^2 - 2C2x*X - 2C2y*Y > C2r^2 + 2C2r*R + R^2 - C2x^2 - C2y^2
....
X^2 + Y^2 - 2Cnx*X - 2Cny*Y > Cnr^2 + 2Cnr*R + R^2 - Cnx^2 - Cny^2

Впровадження

починати від координати білої точки (Xw, Yw),

    var isValidLocation = function(x,y,r){
       var valid = true;
       for (var i = 0; i< circles.length; i++){
          var circle = circles[i];
          valid = valid && ((x*x + y*y - 2*circle.x*x - 2*circle.y*y) > (circle.radius*circle.radius + 2*circle.radius*r + r*r - circle.x*circle.x - circle.y*circle.y));
       }
       return valid;
      };

      var find = function(Xw,Yw,Rw){
        var radius = 0;
        while(true){
          for (var x=-1 * radius ;x <= radius; x++) {
            for (var y=-1 * radius;y <= radius; y++) {
               if (isValidLocation(Xw + x,Yw + y, Rw)){
                 drawCircle(Xw + x,Yw + y,Rw,"#0000FF");
                 return;
               }
            }   
          } 
          radius++;
        }
     }; 

першою координатою, яка виявила задоволення всіх рівнянь, є розташування синього кола


Може хтось, будь ласка, пояснить, що з цим підходом не так?
Пелікан низького польоту

Що важко читати. Використовуйте кілька добрих імен та абстракцій. Чи вбило б ви додати схему?
candied_orange

Наскільки я бачу, цей підхід намагається знайти лише дійсні місця розташування для синього кола, але не найближче можливе місце розташування. Це може бути виправлено, однак підхід також робить (найімовірніше, недійсним) припущення, що існує лише кінцева кількість координат цілих значень.
Док Браун

Він починається від координати білої точки і обходить її, розширюючи пошукову сітку. Через це він не зіткнеться з будь-якою ситуацією, коли він має нескінченну кількість координат. Зрештою, він знайде відповідні координати.
Низьколітаючий пелікан

1
... для правильного рішення цілих координат потрібно використовувати радіус, що збільшується, і зробити простір пошуку колом цього радіуса навколо білої точки. І хоча ОП написав ефективність не його турботу, було б все-таки хорошою ідеєю не перевіряти кожну вже перевірену пару координат у кожному циклі знову і знову.
Doc Brown

0
  • O бути точкою, до якої ти намагаєшся бути поруч
  • P - точка, яку ви шукаєте (центр синього кола
  • r - радіус синього кола
  • C0 .. Cn є центрами всіх кіл, що обмежують розміщення синього на
  • розширене коло - це один із кіл, радіус якого подовжений на r

    Існує деяка додаткова робота, якщо О не знаходиться в центрі кола. Тому зараз припустимо O == C0

Обчисліть усі перетини всіх кіл із С0, використовуючи їх відповідні радіуси плюс r , т. Е. Перетинають розширені кола із розширеним C0. Якщо перехрестя немає, то точка, яку ви шукаєте, знаходиться десь на C0, якщо є перехрестя, для кожного перехрестя перевіряйте, чи знаходиться всередині іншого розширеного кола (ви можете обмежитися колами, які мали перехрестя з C0). Візьміть перше перехрестя, яке не знаходиться в іншому розширеному колі як P, можуть бути й інші.

Якщо між розширеними колами та C0 немає перетинів, які не знаходяться всередині іншого розширеного кола, обчисліть перетини всіх розширених кіл між собою. Потім перевірте ці перехрестя в порядку відстані до О, знову ж таки, якщо будь-яке з перехрестів лежить в межах іншого розширеного кола, якщо так відмінити, якщо ні, це ваш результат.

Якщо ви уявляєте собі це, намалюйте лінію навколо всіх кіл, які вказують на можливе місце для вашого синього кола, якщо об'єднання всіх розширених кіл вказуватиме на область, у якій не може бути синього кола . Точка, яку ви шукаєте, - це найближча точка, яка не в цьому союзі. Якщо на C0 є якась точка, яка не є в тому об'єднанні, яке є рішенням, якщо C0 повністю охоплено, P повинен знаходитись на перетині між двома іншими розширеними колами, і він повинен знаходитися в області, яка не охоплена цей союз (тобто не в розширеному колі ).

Це O (n ^ 2), є кілька способів покращити це, хоча сітка може бути використана для зменшення зусиль парного мудрого пошуку, також я думаю, сортування кіл за їх близькістю до O, (відстань між два кола, зменшені радіо), допоможуть обмежити пошуковий простір для охоплення та перехрестя


0

Можливий пошук рішень

  1. Перевірте, чи біла точка є розчином сама по собі. Він охоплює випадок із 0 червоними колами та тривіальний випадок, коли червоні кола знаходяться далеко від білої точки.
  2. Одне червоне коло.
    1. Біла точка - центр кола. Можливі рішення - нескінченна кількість точок на колі з центром у білій точці та радіусом, що є сумою радіуса синіх кіл та діаметром червоного кола. Назвемо це зеленим колом .
    2. Біла точка - десь інше. Існує лише одне можливе рішення на лінії, яка з'єднує білу точку та центр червоного кола, це радіус синього кола від точки, де червоне коло перетинає лінію до білої точки.
  3. Два або більше червоних кіл.
    1. Візьмемо по черзі червоні кола та шукаємо можливе рішення для кожного з них окремо відповідно до пункту 2 (одного кола).
    2. Для кожної пари червоних кіл перевіримо, чи можна намалювати синє коло, торкаючись обох червоних. Тобто, якщо відстань між їх центрами дорівнює або менше, ніж сума їхніх радіусів плюс діаметр синього кола. Якщо ви можете, то у вас є два (або одне, якщо червоні кола розташовані рівно на один синій діаметр кола) можливих рішень .

Фактичний пошук серед можливих рішень

Тепер у вас є набір точок, які є можливими рішеннями , перебирайте їх і перевіряйте кожен.

  1. Якщо справа насправді є рішенням. Жодне червоне коло не повинно мати центр, ближчий за радіус до цієї точки.
  2. Якщо вона ближче до білої точки, ніж рішення, знайдене раніше.
  3. Якщо у вас зелене коло (точка 2.1)
    • Якщо серед окремих точок немає рішення, яке належить до зеленого кола, то зеленим колом є відповідь.
    • Якщо ви маєте індивідуальні рішення на зеленому колі, і вам потрібно просто будь-яке рішення, тоді просто візьміть один із них.
    • Якщо ви маєте індивідуальні рішення на зеленому колі і вам потрібні всі необмежені кількості рішень, тоді вам потрібно вирішити ще одну проблему. Вам потрібно вирізати із зеленого кола всі дуги, визначені парою окремих розчинів від кожного червоного кола.

NB: Я не кажу, що реалізація алгоритму повинна бути точно описана. Ви можете спробувати підвищити продуктивність, використовуючи динамічне програмування або пропускаючи можливі рішення, коли очевидно, що вони не працюватимуть.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.