chiark / gitweb /
22b: half-working boundary walking
authorBen Harris <bjh21@bjh21.me.uk>
Wed, 5 Jun 2024 19:26:22 +0000 (20:26 +0100)
committerBen Harris <bjh21@bjh21.me.uk>
Wed, 5 Jun 2024 19:26:22 +0000 (20:26 +0100)
We can handle only the case where the next edge is the one we want

22/22b.bqn

index ce191a896943a11425d3c6b3aed5ff7e7b2fd9ff..a9dfbfd44b728cce074b3f581e8daea2dd90e8e9 100644 (file)
@@ -13,20 +13,60 @@ TR←{⟨1,¯1⟩×⌽𝕩}
 Main←{𝕊⟨map,path⟩:
   sidelen←√(+´⥊' '≠map)÷6
   Pad←{ ⟨h,w⟩←≢𝕩 ⋄ »⍟sidelen˘»⍟sidelen(w+2×sidelen)↑˘(h+2×sidelen)↑𝕩 }
-  map ↩ Pad map
+  •Show map ↩ Pad map
   Move←{
     'L' 𝕊 ⟨pos,dir⟩: ⟨pos,TL dir⟩;
     'R' 𝕊 ⟨pos,dir⟩: ⟨pos,TR dir⟩;
     n 𝕊 ⟨pos,dir⟩: Advance⍟n⟨pos,dir⟩
   }
   Advance←{𝕊⟨pos,dir⟩:
-    dest←(≢map)|pos+dir
-    dest↩{ (≢map)|𝕩+dir } •_while_ { ' '=𝕩⊑map } dest
-    ⟨('.'=dest⊑map)⊑⟨pos,dest⟩,dir⟩
+    ⟨dpos,ddir⟩←⟨(≢map)|pos+dir,dir⟩
+    ⟨dpos,ddir⟩ CubeJump ⍟ (' '=dpos⊑map) ↩
+    ('.'=dpos⊑map)⊑⟨⟨pos,dir⟩,⟨dpos,ddir⟩⟩
+  }
+  # To find the where we end up after walking off the boundary of the
+  # net, we walk around that boundary.  On the cube, the cut edges
+  # form a tree, and walking around the boundary forms a depth-first
+  # search of that tree.  When that DFS returns to its starting point,
+  # we've reached the edge we're looking for.
+  #
+  # We can tell whether a particular edge on the boundary goes up or
+  # down the tree by counting faces around each vertex.  If we've seen
+  # one or two faces at a vertex, the edge by which we leave it will
+  # go down.  If we've seen three, we're returning up an edge we've
+  # already seen and we're going up the tree and back to another
+  # vertex we've already seen.
+  #
+  # To move from one edge to the next, we reflect our position and
+  # orientation in an axis passing through the current vertex.  Which
+  # axis it is is dependent on how many faces there are at this
+  # vertex, and we can work that out by trying all the axes and seeing
+  # how many land us on a face.  Because we visit each edge in the
+  # tree twice, there must be an odd number of reflections before we
+  # get back to the start, and therefore we'll end up in the proper
+  # place on the target edge.
+  CubeJump←{𝕊 ⟨pos,dir⟩:
+    ⟨pos,dir⟩↩CubeWalk ⟨pos-dir,dir⟩ # Step back, walk sideways around edge.
+    ⟨pos,-dir⟩ # And then turn around and continue.
+  }
+  CubeWalk←{𝕊 ⟨pos,dir⟩:
+    •Show map Mark ⟨pos,dir⟩
+    cv←⌈⌾((÷⟜(sidelen×dir+TR dir))∘(0.5⊸+)) pos # Current vertex (ahead/right)
+    •Show cv
+    axes←(⊣∾-)⟨[0‿1,1‿0],[1‿0,0‿¯1]⟩
+    Reflect←+˝∘×
+    dests←{
+      ⟨(𝕩⊸Reflect)⌾(-⟜cv) pos, 𝕩 Reflect dir⟩
+    }¨axes
+    •Show map⊸Mark¨dests
+    "Excessively interesting vertex" ! 3=+´' '≠(⊑¨dests)⊑map
+    # Find destination that is on the map but looking off it.
+    ⊑({𝕊⟨pos,dir⟩:∧´⟨0,1⟩=' '=⟨pos,pos+dir⟩⊑map}¨dests)/dests
   }
   pos←⟨sidelen,⊑(sidelen⊏map)⊐'.'⟩
   dir←⟨0,1⟩
   ⟨⟨r,c⟩,d⟩ ← ⟨pos,dir⟩ Move´ ⌽path
+  •Show ⟨⟨r,c⟩,d⟩
   (1000×r+1-sidelen) + (4×c+1-sidelen) + (|1-˜+´⟨2,1⟩×d)
 }