Elide points as needed

This commit is contained in:
Pyrex 2022-12-20 15:04:00 -08:00
parent 60f1c2e112
commit 281ed4b40f

View File

@ -1047,9 +1047,9 @@ function rope:draw(artificial_dx,artificial_dy)
local color=8 local color=8
if (highlight==0) color=12 if (highlight==0) color=12
if self.latch.dx==-1 and self.latch.dy==0 then if self.latch.dx==-1 and self.latch.dy==0 then
rectfill(x+1,y,x+3,y+1,color) rectfill(x+1,y-1,x+3,y,color)
elseif self.latch.dx==1 and self.latch.dy==0 then elseif self.latch.dx==1 and self.latch.dy==0 then
rectfill(x-1,y,x-3,y+1,color) rectfill(x-1,y-1,x-3,y,color)
elseif self.latch.dx==0 and self.latch.dy==-1 then elseif self.latch.dx==0 and self.latch.dy==-1 then
rectfill(x,y+1,x-1,y+3,color) rectfill(x,y+1,x-1,y+3,color)
elseif self.latch.dx==0 and self.latch.dy==1 then elseif self.latch.dx==0 and self.latch.dy==1 then
@ -1090,17 +1090,69 @@ function rope:drag_src(x,y)
self:drag(self.src,x,y) self:drag(self.src,x,y)
end end
function rope:drag( function rope:drag(n1,ax_new,ay_new)
n1,ax_new,ay_new
)
-- TODO: stepwise? -- TODO: stepwise?
rope:_drag1(n1,ax_new,ay_new) self:_relax()
self:_drag(n1,ax_new,ay_new)
self:_relax()
end
function rope:_relax()
local n0=self.src
while true do
if (n0==nil) return
local n1=n0.next
if (n1==nil) return
local n2=n1.next
if (n2==nil) return
if n1.associated_with!=nil then
local x0,y0=n0.ax,n0.ay
local x1,y1=n1.ax,n1.ay
local x2,y2=n2.ax,n2.ay
if (x0>x2) x0,y0,x2,y2=x2,y2,x0,y0
local dx=x2-x0
local dy=y2-y0
local adx,ady
local x1_new,y1_new
if abs(dx)>abs(dy) then
local dprop=(x1-x0)/dx
x1_new,y1_new=x1,y0+dprop*(y2-y0)
ady=sgn0(y1_new-y1)
adx=0
if (y0>y2) adx=ady
if (y0<y2) adx=-ady
else
local dprop=(y1-y0)/dy
x1_new,y1_new=x0+dprop*(x2-x0),y1
adx=sgn0(x1_new-x1)
ady=0
if (y0>y2) ady=adx
if (y0<y2) ady=-adx
end
if adx!=0 and ady!=0 and (n1.associated_with.adx!=adx or n1.associated_with.ady!=ady) then
--self:_drag(n1,x1_new,y1_new)
n0=n1.prev
n2=n1.next
n0.next=n2
n2.prev=n0
n1.next=nil
n1.prev=nil
else n0=n0.next end
else n0=n0.next end
end
end end
-- TODO: Upon adding a point, start from there to see if we need another -- TODO: Upon adding a point, start from there to see if we need another
-- rather than adding at most one -- rather than adding at most one
function rope:_drag1(n1,ax1_new,ay1_new) function rope:_drag(n1,ax1_new,ay1_new)
local function _sweep_radar(ax_pivot,ay_pivot,ax_far0,ay_far0,ax_far1,ay_far1) local function _sweep_radar(ax_pivot,ay_pivot,ax_far0,ay_far0,ax_far1,ay_far1)
if (ax_far0==ax_far1 and ay_far0==ay_far1) return nil
if ax_far0==ax_far1 then if ax_far0==ax_far1 then
local ax_far=ax_far0 local ax_far=ax_far0
local ax0,ax1=_mnmx(ax_pivot,ax_far) local ax0,ax1=_mnmx(ax_pivot,ax_far)
@ -1126,6 +1178,8 @@ function rope:_drag1(n1,ax1_new,ay1_new)
for ax_far_new in _stepfrom(ax_far0,ax_far1) do for ax_far_new in _stepfrom(ax_far0,ax_far1) do
for _,anchor in level:anchor_points() do for _,anchor in level:anchor_points() do
if if
-- anchor.ax!=ax_pivot and anchor.ay!=ay_pivot and
-- anchor.ax!=ax_new and anchor.ay!=ay_new and
(ay0<=anchor.ay and anchor.ay<=ay1) and (ay0<=anchor.ay and anchor.ay<=ay1) and
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far_old,ay_far)!= _which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far_old,ay_far)!=
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far_new,ay_far) _which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far_new,ay_far)
@ -1141,13 +1195,17 @@ function rope:_drag1(n1,ax1_new,ay1_new)
end end
local ax1_old,ay1_old=n1.ax,n1.ay local ax1_old,ay1_old=n1.ax,n1.ay
n1.ax=ax1_new
n1.ay=ay1_new
local n0=n1.prev local n0=n1.prev
while true do while true do
if (n0==nil) break if (n0==nil) break
local anch=_sweep_radar(n0.ax,n0.ay,ax1_old,ay1_old,ax1_new,ay1_new) local anch=_sweep_radar(n0.ax,n0.ay,ax1_old,ay1_old,ax1_new,ay1_new)
if (anch==nil) break if (anch==nil) break
local n05={ax=anch.ax,ay=anch.ay,prev=n0,next=n1} if (anch.ax==n0.ax and anch.y==n0.ay) break
if (anch.ax==n1.ax and anch.y==n1.ay) break
local n05={ax=anch.ax,ay=anch.ay,associated_with=anch,prev=n0,next=n1}
n0.next=n05 n0.next=n05
n1.prev=n05 n1.prev=n05
n0=n05 n0=n05
@ -1158,14 +1216,13 @@ function rope:_drag1(n1,ax1_new,ay1_new)
if (n2==nil) break if (n2==nil) break
local anch=_sweep_radar(n2.ax,n2.ay,ax1_old,ay1_old,ax1_new,ay1_new) local anch=_sweep_radar(n2.ax,n2.ay,ax1_old,ay1_old,ax1_new,ay1_new)
if (anch==nil) break if (anch==nil) break
local n15={ax=anch.ax,ay=anch.ay,prev=n1,next=n2} if (anch.ax==n1.ax and anch.y==n1.ay) break
if (anch.ax==n2.ax and anch.y==n2.ay) break
local n15={ax=anch.ax,ay=anch.ay,associated_with=anch,prev=n1,next=n2}
n1.next=n15 n1.next=n15
n2.prev=n15 n2.prev=n15
n2=n15 n2=n15
end end
n1.ax=ax1_new
n1.ay=ay1_new
end end
function _stepfrom(x0,x1) function _stepfrom(x0,x1)