2016-09-29 8 views
0

Я пытаюсь понять, отображается ли множество точек другой точке. У меня есть геометрия и точка наблюдения (красная точка на изображении). Сетка разбивается на сегменты линии, каждая с центром (синие стрелки). Мне нужно определить, может ли точка наблюдения видеть центр сегментов линии без какого-либо другого сегмента линии, находящегося между ними.Определить, видны ли точки.

Метод, который я использовал, пытается вычислить линию, перпендикулярную линии между точкой наблюдения и каждым из центров. Затем проецируем каждый из сегментов линии на эту строку и проверяем, находится ли центр, с которым я связан, между начальной и конечной точкой проецируемого сегмента линии. Я либо все вижу, либо невидимо для наблюдательного пункта.

Я использую это как reference

Мой вопрос состоит из двух частей. Во-первых, я не могу понять, почему это не работает, а во-вторых, есть ли лучший способ сделать это?

bool projectPointOntoLine(point observation, vector<segment> segments, int currentIndex){ 

point currentPoint = segments[currentIndex].getCenter(); 

double dx = observation.getX() - currentPoint.getX(); 
double dy = observation.getY() - currentPoint.getY(); 

double m = -dy/dx; 
double mm = m*m; 

double newX = calculateNewX(currentPoint.getX(), currentPoint.getY(), m, mm); 
double newY = calculateNewY(currentPoint.getX(), currentPoint.getY(), m, mm); 

long double minDist = sqrt((currentPoint.getX() - observation.getX())*(currentPoint.getX() - observation.getX()) + (currentPoint.getY() - observation.getY())*(currentPoint.getY() - observation.getY())); 

bool visible = true; 

for(unsigned ii = 0; ii < segments.size(); ii++){ 
    if(ii != currentIndex){ 

     point mid = segments[ii].getStart(); 

     long double dist = sqrt((mid.getX() - observation.getX())*(mid.getX() - observation.getX()) + (mid.getY() - observation.getY())*(mid.getY() - observation.getY())); 

     if(dist < minDist) { 

      point start = segments[ii].getStart(); 
      point end = segments[ii].getEnd(); 

      double newStartX = calculateNewX(start.getX(), start.getY(), m, mm); 
      double newStartY = calculateNewY(start.getX(), start.getY(), m, mm); 

      double newEndX = calculateNewX(end.getX(), end.getY(), m, mm); 
      double newEndY = calculateNewY(end.getX(), end.getY(), m, mm); 

      if ((newX >= newStartX && newEndX >= newX)){// && (newY >= newStartY && newEndY >= newY)) { 
       visible = false; 
      } 
      else if ((newX >= newEndX && newStartX >= newX)){//} && (newY >= newEndY && newStartY >= newY)) { 
       visible = false; 
      } 
     } 

    } 
} 

return visible; 
} 

double calculateNewX(double x, double y, double gradient, double gradientSquared){ 
return (1/(1 + gradientSquared))*(x) + (gradient/(1 + gradientSquared))*(y); 
} 

double calculateNewY(double x, double y, double gradient, double gradientSquared){ 
return (gradient/(1 + gradientSquared))*(x) + (gradientSquared/(1 + gradientSquared))*(y); 
} 

Это дает мне следующий результат:

enter image description here

Который является только половина затенения.

+0

Что делают 'calculateNewX' и' calculateNewY'? Для удобочитаемости рассмотрим объединение их в одну функцию, которая принимает «точку» и возвращает «точку». Какова цель «шкалы»? Масштабирование, по-видимому, имеет значение при расчете 'm'. – chtz

+0

Жаль об этом. Масштабирование было, когда я пытался что-то раньше. Я обновил раздел кода сейчас. –

ответ

0

Видимо проблема здесь:

if((newX > newStartX && newEndX > newX) && (newY > newStartY && newEndY > newY)){ 
     visible = false; 
    } 

Вы предположить, что newStartX всегда меньше, чем newEndX (то же самое с Y). Это не обязательно так. В зависимости от взаимной ориентации сегмента и линии для проецирования конечные точки могут переворачиваться.

+0

Должен ли я тогда просто добавить и дополнительную проверку, если 'originalStartX' меньше, чем' originalEndX', иначе поменяйте точки вокруг и сделайте то же самое для координат y? –

 Смежные вопросы

  • Нет связанных вопросов^_^