网格-障碍物/如何计算“视野”

时间:2020-04-27 23:06:53

标签: algorithm math grid

我的英语不是我的母语,我不知道它的标题,如何清楚地解释它,也不知道它是否是正确的术语。我曾尝试先在Google上进行搜索,但由于上述原因,我找不到任何相关内容。

首先请您查看imgur相册:https://imgur.com/a/4mMuCil

所以...

  • 黑色方块是一个“障碍”
  • 红场是一个“参与者”
  • 灰色方块是“玩家无法看到的区域”

根据玩家到障碍物的距离,玩家可以看到更多或更少的“东西”

是否存在一个通用公式来确定他可以看到或看不到的区域? 或者我必须根据玩家相对于障碍物的位置写一个独特的公式

对不起,如果我写的东西没有道理 谢谢您的帮助

编辑:

点球员(5,0);

点障碍物(4,2);

.....o...
.........
....@....
.........
.....#...
.....##..
.....###.
.....####
......###

2 个答案:

答案 0 :(得分:0)

假设玩家在(0,0),障碍在(j,k),且j> 0和k> = 0。

如果(2j-1)y> =(2k + 1)x或(2k-1)x> =(2j + 1)y,则在(x,y)处的正方形将可见。

将此规则应用于其他三个象限很简单。

答案 1 :(得分:0)

这需要一些工作。我会说说使其生效的步骤:

(1)让我们定义玩家位置p和障碍物位置o

我们知道我们想在障碍物后画一个“三角形”。

(2)让我们根据接近度定义角度。

越近,角度越大,因此如果距离为1,我将角度设置为45,随着玩家离障碍物越远,角度就减小。角度为5 + (max(0, 50 - distance * 10))。您可以调整这个角度。

(3)让我们建立一个大三角形。第一个顶点是障碍。然后,从玩家处越过障碍线。将此线绕障碍物顺时针旋转半角(获取第二个顶点),逆时针旋转半角(获取第三个顶点),如图所示:enter image description here

(4)最后,迭代到矩阵,并针对每个位置询问坐标是否在三角形内。

#include <bits/stdc++.h>
using namespace std;

struct point{
    float x, y;
    point(){}
    point(float x, float y){this->x = x; this->y = y;}
    //point(int x, int y){this->x = x; this->y = y;}
};

point rotate(point pivot, float angle, point p, bool clockwise){
    float s = sin(angle);
    float c = cos(angle);

    p.x -= pivot.x;
    p.y -= pivot.y;

    if(clockwise){
        return point(p.x * c + p.y * s + pivot.x, -p.x * s + p.y * c + pivot.y);
    }
    else{
        return point(p.x * c - p.y * s + pivot.x, p.x * s + p.y * c + pivot.y);
    }
}

float triangleArea(point p1, point p2, point p3) {         //find area of triangle formed by p1, p2 and p3
   return abs((p1.x*(p2.y-p3.y) + p2.x*(p3.y-p1.y)+ p3.x*(p1.y-p2.y))/2.0);
}

bool inside(point p1, point p2, point p3, point p) {     //check whether p is inside or outside
   float area = triangleArea (p1, p2, p3);          //area of triangle ABC
   float area1 = triangleArea (p, p2, p3);         //area of PBC
   float area2 = triangleArea (p1, p, p3);         //area of APC
   float area3 = triangleArea (p1, p2, p);        //area of ABP

   return abs(area - area1 + area2 + area3) < 1;        //when three triangles are forming the whole triangle
}

char m[9][9];

point player(4, 0);
point obstacle(4, 2);

float angle(){
    float dist = sqrt(pow(player.x - obstacle.x, 2) + pow(player.y - obstacle.y, 2));
    cout<<"dist: "<<(5.0 + max(0.0, 50.0 - 10.0 * dist))<<endl;
    return (5.0 + max(0.0, 50.0 - 10.0 * dist)) * 0.0174533;
}

void print(){
    for(int i = 0; i < 9; i++){
        for(int j = 0; j < 9; j++){
            cout<<m[i][j];
        }
        cout<<endl;
    }
}

int main(){
    for(int i = 0; i < 9; i++){
        for(int j = 0; j < 9; j++){
            m[i][j] = '.';
        }
    }
    m[(int)player.y][(int)player.x] = 'o';
    m[(int)obstacle.y][(int)obstacle.x] = '@';

    float rad = angle();

    point end(20.0 * (obstacle.x - player.x) + obstacle.x, 20.0 * (player.y - obstacle.y) + obstacle.y);
    point p2 = rotate(obstacle, rad / 2.0, end, true);
    point p3 = rotate(obstacle, rad / 2.0, end, false);

    for(int i = 0; i < 9; i++){
        for(int j = 0; j < 9; j++){
            if(i == (int) player.y && j == (int) player.x) continue;
            if(i == (int) obstacle.y && j == (int) obstacle.x) continue;
            if(inside(obstacle, p2, p3, point(j, i))) m[i][j] = '#';
        }
    }

    print();

    return 0;
}

输出:

....o....                                                                                                                                                                          
.........                                                                                                                                                                          
....@....                                                                                                                                                                          
....#....                                                                                                                                                                          
....#....                                                                                                                                                                          
....#....                                                                                                                                                                          
...###...                                                                                                                                                                          
...###...                                                                                                                                                                          
...###...