确定点是否可见

时间:2016-09-29 14:26:44

标签: c++ line linear-algebra points

我想弄清楚一组点是否对另一个点可见。我有一个几何网格和一个观察点(图像上的红点)。网格被分成线段,每个线段都有一个中心(蓝色箭头)。我需要确定观察点是否可以看到线段的中心,而其间没有任何其他线段。

我一直遵循的方法是尝试计算垂直于观察点和每个中心之间的直线的直线。然后将每个线段投影到该线上,并检查我所关注的中心是否位于投影线段的起点和终点之间。我要么让所有观察点都可见或看不见。

我将其用作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

这只是影子的一半。

1 个答案:

答案 0 :(得分:0)

显然问题在于:

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

您认为newStartX始终小于newEndX(与Y相同)。情况不一定如此。根据段的相互方向和要投影的线,端点可能会翻转。