matlab实现可视图法

首先,读取并显示图片。
main.m

clear all;
clc;
img=imread('img.png');

并且手动选择顶点

[p1,p2]=getpts;
hold on;

matlab实现可视图法

之后开始循环遍历顶点

for n=1:length(p1)
  for m=n+1:length(p1)
       if (square(p1(n),p1(m),p2(n),p2(m),p1,p2) == 0) & (triangle(p1(n),p1(m),p2(n),p2(m),p1,p2)) == 0 & (star(p1(n),p1(m),p2(n),p2(m),p1,p2)) == 0
       plot([p1(n),p1(m)],[p2(n),p2(m)],'b-'); %连接两个符合条件的顶点
       end
  end
end

在连接两个顶点之前,先要if判断这两点连线是否经过障碍物。主要原理是:将直线写成y=kx+b的形式,将图形的所有顶点坐标带入y-kx-b,如果得到的结果同时大于零或者同时小于零,说明图形的所有顶点都在直线的同侧,即直线不过图形。否则说明图形的顶点分布在直线两侧,直线过图形。
在if判断中调用了square(),triangle(),star()三个函数,以square()为例
square.m

function isThrough1=square(x1,x2,y1,y2,p1,p2) 
%判断两点连线是否与正方形相交
flag1 = getline(x1,x2,y1,y2,p1(1),p2(1));
flag2 = getline(x1,x2,y1,y2,p1(2),p2(2));
flag3 = getline(x1,x2,y1,y2,p1(3),p2(3));
flag4 = getline(x1,x2,y1,y2,p1(4),p2(4));
if((flag1 >= 0 && flag2 >= 0 && flag3 >= 0 && flag4 >= 0) | (flag1 <= 0 && flag2 <= 0 && flag3 <= 0 && flag4 <= 0)) %根据原理判断连线是否与图形相交
    isThrough1 = 0;%连线不与正方形相交
else
    isThrough1 = 1;%连线与正方形相交
end

在square函数中,先调用了getline函数。
getline.m

function flag=getline(x1,x2,y1,y2,x,y) 
%由两点得到y=kx+b形式的直线方程
k = (y2 - y1)/(x2 - x1);
b = y1;
temp = y - k * (x - x1) - b;
if temp > 0 
    flag = 1;
elseif temp < 0
    flag = -1;
else 
    flag = 0;
end

getline函数主要作用是计算y-kx-b的值,并返回flag的值给square函数。
最后得到可视图:
matlab实现可视图法

总结可视图法步骤:

  1. 读取地图,手动获取顶点
  2. 依次遍历顶点,根据判据判断当前两个顶点的连线是否经过正方形、三角形以及五边形区域
  3. 若当前两个顶点的连线都不经过障碍物区域,则画出两点连线
  4. 循环结束,画出可视图
    代码下载链接
    但是我发现,我的代码好像会少画几根线,现在还没找到原因。。。水平有限,敬请指正
上一篇:leetcode笔记总结——(5)简化路径(python和C++实现)


下一篇:关于C++的输入用法