📄 rectwave.m
字号:
function path = RectWave(map, startPos, endPos)
%map——二维数组图 0: passable 1: obstacle
% startPos: Original Position
% endPos: Target Postion
% Search the shortest path by rect wave propagation algorithm
% Rectwave should search the path from the DTM begin with principal
% neibourgh grids, else it will make zigzag path
%路径规划
%s->Start, G->Goal
S.x = startPos(1);
S.y = startPos(2);
G.x = endPos(1);
G.y = endPos(2);
DTM = GetDistanceTransform(map, S, G);
path = FindPathFromDTM(DTM, S, G);
return;
%%%%%%%%%%%%%
%make DistanceTransformMatrix
%+++++++++++++++++++++++++++++++++++++++++++++++++
function DTM = GetDistanceTransform(map, S, G)
DTM = Inf * ones(size(map));
DTM(G.y, G.x) = 0;
G.cost = 0;
WFT = [];
WFT = INSERT_NODE(WFT, G);
cur = G;
while ~(cur.x==S.x & cur.y==S.y) & length(WFT)~=0
[cur WFT] = GetTail(WFT);
% plot(cur.x, cur.y, 'k+'); drawnow;
[WFT DTM] = PropagateWave(map, DTM, WFT, cur);
end
return;
%=================================================
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Find path from Distance Transform Matrix
%+++++++++++++++++++++++++++++++++++++++++++++++
function path = FindPathFromDTM(DTM, S, G)
if DTM(S.y, S.x) == Inf%寻路失败
path = [];
return;
end
[Ymax Xmax] = size(DTM);
p = S;
path = S;
j = 0; % 0 : start with N4(p) or principal grids; 4: start with ND(p) or diagonal grids
while DTM(p.y, p.x)~=0
for k = j : j+7
x = p.x; y = p.y;
switch(mod(k,8))
case 0
x = x + 1;
case 1
x = x - 1;
case 2
y = y - 1;
case 3
y = y + 1;
case 4
x = x + 1;
y = y + 1;
case 5
x = x - 1;
y = y - 1;
case 6
x = x + 1;
y = y - 1;
case 7
x = x - 1;
y = y + 1;
end
if x<1 | y<1 | x>Xmax | y>Ymax
continue;
end
if DTM(y,x) == DTM(p.y, p.x)-1
p.x = x; p.y = y;
% j = k;
break;
end
end
path = [path, p];
end
%=================================================
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%name: insert_node(): 将节点插入列表并排序
%%%%%%%%%%=======begining of insert_node=========%%%%%%%%%%%%%%%%%%%%
function NewWFT = INSERT_NODE(WFT, p)
% p可能在WFT里有重复,卍代码是删除WFT重复p,但实验表明删除重复点反而增加耗时
% global tag;
% if tag(p.y, p.x) > 0
% WFT = Delete(p, WFT);
% else
% tag(p.y, p.x) = tag(p.y, p.x)+1;
% end
%以下代码是对WFT进行排序,但实验表明排序也使算法耗时增加
% if isempty(WFT) %a new or null list
% NewWFT = p;
% else
% num = length(WFT);
% while num~=0 & WFT(num).cost<p.cost
% num = num-1;
% end
% NewWFT = [WFT(1:num), p, WFT(num+1:end)];
% end
%以下代码是将p直接插入WFT前面,既不排序也不删除重复点,但实验表明耗时反而最少
NewWFT = [p WFT];
%%%%%%%%%%=======end of insert_node=========%%%%%%%%%%%%%%%%%%%%%%
function NewList = Delete(X, List)
num = length(List);
while num~=0 & ~(List(num).x==X.x & List(num).y==X.y)
num = num - 1;
end
% 不考虑状态增大或者减小吗?
NewList = [List(1:num-1), List(num+1:end)];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%function: GetTail(): 从List中取出末尾节点并修改List
%%%%%%%%%%======= begining =========%%%%%%%%%%%%%%%%%%%%
function [y, newlist] = GetTail(list)
if isempty(list)
y = [];
newlist = [];
else
y = list(end);
newlist = list(1 : end-1);
end
%%%%%%%%%%=======end of get_node()=========%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%function: Ex_nods(): 扩展节点
%%%%%%%%%%======= begining =========%%%%%%%%%%%%%%%%%%%%
function [newlist newVmap] = PropagateWave(map, Vmap, openlist, p)
global tag;
[Ymax Xmax] = size(map);
for k = 1 : 8
x = p.x; y = p.y; d=1;
switch(k)
case 1
x = x - 1;
case 2
x = x + 1;
case 3
y = y - 1;
case 4
y = y + 1;
case 5
x = x - 1;
y = y - 1;
case 6
x = x + 1;
y = y + 1;
case 7
x = x - 1;
y = y + 1;
case 8
x = x + 1;
y = y - 1;
end
if x<1 | y<1 | x>Xmax | y>Ymax | map(y, x)==1 | Vmap(y, x)<=Vmap(p.y, p.x)+d
continue;
else
Vmap(y, x) = Vmap(p.y, p.x)+d;
temp.x = x; temp.y = y;
temp.cost = Vmap(y,x);
openlist = INSERT_NODE(openlist, temp);
end
end
newlist = openlist;
newVmap = Vmap;
return;
%%%%%%%%%%======= end =========%%%%%%%%%%%%%%%%%%%%%%
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -