2

The Wikipedia Article on the Hilbert Cube includes functions that encode/decode arbitrary indices to/from arbitrary points on the Hilbert Curve. Those algorithms aren't constant-time. Is there a constant-time algorithm that, given an actual point on the curve (and, perhaps, some required state), generates the next point (and the next state)?

Formally, I want a type State, and a tuple (initialState, nextState) :: (State, State -> ((Nat, Nat), State), such that each application of nextState gives us the next point of the Hilbert curve, and such that that nextState is optimal, which is probably not the case for the algorithm presented on Wikipedia, since it possibly misses the opportunity for incremental computation that we have here. Illustration:

data State = _

initialState :: State
initialState = _

-- This must be optimal
nextState :: State -> ((Nat, Nat), State)
nextState = _

-- Returns the `nth point` of the hilbert curve
hilbertPoint :: Nat -> (Nat, Nat)
hilbertPoint n = iterate (snd.nextState) initialState !! n
MaiaVictor
  • 51,090
  • 44
  • 144
  • 286
  • When you say "generating points on the fly," do you mean "generating random points on the Hilbert curve," or something else? – templatetypedef Aug 28 '16 at 21:16
  • @templatetypedef maybe I was ambiguous, so I've added layers of redundancy on the question to make it as specific as possible. – MaiaVictor Aug 28 '16 at 21:34
  • Can you elaborate on what you mean by "the next point on the curve?" The curve is continuous. – templatetypedef Aug 28 '16 at 21:37
  • @templatetypedef the Wikipedia article has a function, `d2xy : Int -> Int -> (Int, Int)` to convert integers to 2D points on the hilbert curve in a square divided into `n by n` cells. `map (d2xy n) [0..]` is the list of points I want to generate incrementally. – MaiaVictor Aug 28 '16 at 21:59
  • @Gene why did you delete your answer? I found it very useful. – MaiaVictor Aug 28 '16 at 22:01
  • Well, it has nothing to do with Haskell. I know little of that language. But I'll undelete since you asked... – Gene Aug 28 '16 at 23:57
  • If you are interested in being able to generate the n-th point along the curve directly, have a look at [this github repo](https://github.com/galtay/hilbert_curve) – ErikR Aug 29 '16 at 05:52

1 Answers1

0

If you mean "Is there an algorithm for generating the vertices of a Hilbert curve in sequence with O(1) cost per vertex?" the answer is yes. This is a standard exercise in recursion. If you have the usual turtle graphics primitives for emitting the vertices, it looks like this:

-- Angle must be + or - 90.0 degrees.
procedure Hilbert(Order : in Natural;
                  Angle : in Float) is
   Step : constant Float := 1.0; -- length of base case edge
begin
   if Order > 0 then
      Turn(Angle);
      Hilbert(Order - 1, -Angle);
      Walk(Step);
      Turn(-Angle);
      Hilbert(Order - 1,  Angle);
      Walk(Step);
      Hilbert(Order - 1,  Angle);
      Turn(-Angle);
      Walk(Step);
      Hilbert(Order - 1, -Angle);
      Turn(Angle);
   end if;
end Hilbert;

Initiate the recursion with

Hilbert(7, 90.0);

to get a 7th order curve.

Addition

Since you seem to be interested in an iterator pattern, you can either use the logic above and a language (like Python or Ruby) with generators, or you can implement the generator yourself with the usual techniques for recursive to iterative code conversion.

Gene
  • 46,253
  • 4
  • 58
  • 96
  • Thanks for undeleting the answer. I only added the Haskell flag because it is the language on which I was comfortable to express the problem precisely. I ported your answer [to JavaScript](http://lpaste.net/181204) and turns out, as I suspected, it is about 4 times faster than [the Wikipedia version](http://lpaste.net/181205) when you absolutely must generate all points (which is my case). Thank you. – MaiaVictor Aug 29 '16 at 00:01