Есть точка внутри круга, как найти ближайшую к ней точку на круге

434
10 октября 2017, 06:17

В общем есть пример https://codepen.io/korolariya/pen/KXQaJK?editors=1111 в методе

preMove(point:Point){
    if(this.lake.checkPoint(point)){
          this.goToPoint(new Point(point.y, -1 * point.x));
      return;
    }
    this.moveTo(point);
  }

извиняйте за грязноту кода, писал на скорую руку

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

Если обобщить то получается у нас есть точка внутри окружности, нужно найти ближайшую на окружности, я так понимаю это вектор из центра до точки длинной в радиус, а потом как то по окружности переместить бонстика в нужную точку. Или есть какой то ещё способ?

В общем задача такая, есть озеро, это самая большая окружность, синий кружок это рыбак, он за мышкой плавает, ну желательно мышь держать внутри озера, подплывая к берегу бонстик(красный шарик) догоняет рыбака и там другая история. Только бонстик сейчас туповат=)

Задал вопрос на английском, очень сильно впечатлен результатом, чел просто взял и сделал на канвасе, https://stackoverflow.com/questions/46644693/how-to-make-sure-that-the-monster-is-not-in-the-circle/46645698#46645698 Я в афиге

Answer 1

Предположим, есть круг радиуса R с центром в точке O. Уравнение круга x^2+y^2=R^2 Есть точка x0,y0. Нужно найти ближайшую точку на окружности. Тут все просто. Найдем a=arctang y/x - это угол, под которым вектор из центра лежит к оси x. Тогда координаты ближайшей точки будут R cos a, R sin a. Или посчитать R/(x0^2+y0^2) и умножить на это число обе координаты.

Answer 2

Коротко:

  • взять вектор из центра окружности в рассматриваемую точку
    • просто разность координат рассматриваемой точки и центра окружности, именно в таком порядке
  • привести его к длине, равной радиусу окружности
    • домножить вышеупомянутый вектор (покомпонентно) на такое число, чтобы его длина стала равна радиусу окружности; радиус вы знаете, длину тоже, вопрос одного деления
  • прибавить полученный вектор к центру окружности

Псевдокод на векторах:

функция ближайший_к_окружности(вектор2 точка, вектор2 центр, число радиус): вектор2
  вектор2 разность = точка - центр;
  вернуть(
    центр + (разность * (радиус / длина(разность)))
  );

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

Так вы узнаете, где объект должен будет оказаться "в условно бесконечном будущем без воздействий". Но нужно понять, где он должен оказаться на очередном шаге, чтобы остаться на дуге. Тут математика не сложнее, но объёма побольше.

Он сместится по окружности на расстояние, равное требуемой линейной скорости, если пункт назначения ещё достаточно далеко (дойти до пункта назначения за один шаг нельзя). Но обратите внимание, что это расстояние вдоль дуги, а не по прямой. Какому расстоянию по прямой эквивалентно смещение по дуге за шаг, можно посчитать заранее, сохранить и сравнивать впоследствии с ним.

функция порог_расстояния(число скорость, число радиус): число
  вещественный угол = скорость / радиус;
  вектор2 радиус_на_оси = [радиус, 0]
  вектор2 радиус_повёрнутый = [радиус * cos(угол), радиус * sin(угол)];
  вектор2 смещение = радиус_повёрнутый - радиус_на_оси;
  вернуть(смещение.длина);

Нарисуйте на координатной плоскости эту операцию по шагам. Станет понятнее.

Во-от... И если пункт назначения достаточно далеко, то очередной шаг будет поворотом точки вокруг центра окружности на угол величины поворот := скорость / радиус. Но вдоль окружности можно двигаться в две стороны: повернувшись на углы поворот и -поворот вокруг центра окружности.

С помощью поворота на плоскости для каждого из двух, можно выяснить обе точки-кандидата для очередного шага, но надо выбрать одну. В большинстве практических задач используется "через которую ближе".

  • Можно вычислить это, посчитав, от какой из точек-кандидатов расстояние до цели меньше.
  • А можно через скалярное произведение узнать, какой из двух векторов смещения ближе к нужному по направлению (у какой пары оно больше, у тех направления ближе). Первый проще понять, второй вычислительно "дешевле", т. к. не требует квадратных корней.
READ ALSO
Node.js: Передача данных на клиент

Node.js: Передача данных на клиент

У меня есть nodejs сервер на express

314
Как конвертировать дом элемент в строку

Как конвертировать дом элемент в строку

Как конвертировать дом элемент в строку, или может еще какую магию посоветуете что бы можно было этот самый элемент целиком хранить localStorage

228
Ошибка “$apply already in progress” в событии FileReader.onloadstart

Ошибка “$apply already in progress” в событии FileReader.onloadstart

Столкнулся с разным поведением скрипта в браузерах Mozilla Firefox v560 и Google Chrome v61

208
js который экспортирует таблицу в excel

js который экспортирует таблицу в excel

Нашел на просторах интернета данный скрипт:

201