Shortest Path
Shortest path from one point to another
Last updated
Shortest path from one point to another
Last updated
//Shortest Path
def ner(st,en,dr,cr:var[]..[])
{
c1 = List.FilterByBoolMask(cr,st.DistanceTo(cr)==0)["in"];
e1 = List.Flatten(List.SetDifference(List.Transpose([c1.StartPoint,c1.EndPoint])<1>,st),-1);
c2 = List.SortByKey(c1, e1.DistanceTo(en))["sorted list"];
e2 = List.SortByKey(e1, e1.DistanceTo(en))["sorted list"];
d2 = c2.TangentAtParameter(c2.ParameterAtPoint(e2));
b2 = Vector.ByTwoPoints(c2.StartPoint,c2.EndPoint).IsParallel(dr);
c3 = List.IsEmpty(List.FilterByBoolMask(c2,b2)["in"]) ? c2[0] : List.FilterByBoolMask(c2,b2)["in"][0];
e3 = List.IsEmpty(List.FilterByBoolMask(e2,b2)["in"]) ? e2[0] : List.FilterByBoolMask(e2,b2)["in"][0];
d3 = c3.TangentAtParameter(c3.ParameterAtPoint(e3));
return [[c2[0],e2[0],d2[0]],[c3,e3,d3]];
};
def shPh1 (st,en,crvs:var[]..[])
{
dr = Vector.ByTwoPoints(st,en);
ds = st.DistanceTo(en);
shPth1 = [Imperative]
{
ph = [];
ct = 0;
while (ds > 0)
{
cr = ner(st,en,dr,crvs)[0];
ph[ct] = cr[0];
st = cr[1];
dr = cr[2];
crvs = List.SetDifference(crvs,ph);
ds = st.DistanceTo(en);
ct = ct + 1;
}
return ph;
}
return shPth1;
};
def shPh2 (en1,en2,en,crvs:var[]..[])
{
cv1 = Math.Sum(shPh1 (en1,en,crvs).Length);
cv2 = Math.Sum(shPh1 (en2,en,crvs).Length);
return cv1 >= cv2 ? 1 : 0;
};
def shPh3 (st1,en1,cvs:var[]..[])
{
return = [Imperative]
{
cv1 = ner(st1,en1,Vector.ByTwoPoints(st1,en1),cvs);
ne1 = cv1[shPh2 (cv1[0][1],cv1[1][1],en1,cvs)];
ph = [ne1[0]];
st = ne1[1];
dr = ne1[2];
ds = st.DistanceTo(en1);
ct = 1;
while (ds > 0)
{
cs = List.SetDifference(cvs,ph);
cr = ner(st,en1,dr,cs);
ne = cr[shPh2 (cr[0][1],cr[1][1],en1,cs)];
ph[ct] = ne[0];
st = ne[1];
dr = ne[2];
ds = st.DistanceTo(en1);
ct = ct + 1;
}
return ph;
}
};
//Sample Grid
a = 0..100..10;
p1 = Point.ByCoordinates(a<1>,a<2>);
p2 = List.Transpose(p1);
p3 = List.DropItems(List.Sublists(p1<1>,0..1,1)<1>,-1);
p4 = List.DropItems(List.Sublists(p2<1>,0..1,1)<1>,-1);
l1 = Line.ByBestFitThroughPoints(List.Flatten([p3,p4],2));
r1 = Rectangle.ByCornerPoints(Point.ByCoordinates([0,0,100,100],[0,100,100,0]));
r2 = Rectangle.ByCornerPoints(Point.ByCoordinates([30,30,70,70],[10,70,70,10]));
s1 = r1.Patch().TrimWithEdgeLoops([r1,r2]);
l2 = List.RemoveIfNot(List.Flatten(l1.Intersect(s1),-1),"Line");