-
Notifications
You must be signed in to change notification settings - Fork 3
/
hilbert.js
149 lines (142 loc) · 4.01 KB
/
hilbert.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
* Copyright 2010 Barricane Technology Ltd., All rights reserved.
*
* Released under the MIT licence.
*/
/**
* Battenburg is simply a 2x2 matrix with non-mutating
* methods.
*
* @param {Object} a
* @param {Object} b
* @param {Object} c
* @param {Object} d
*/
function Battenburg(a, b, c, d) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
/**
* Returns a new battenburg mirrored on the x=0 line, i.e. swaps up and down.
*/
Battenburg.prototype.mirror_x = function() {
return new Battenburg(this.c, this.d, this.a, this.b);
}
/**
* Returns a new battenburg rotated 90 degress clockwise.
*/
Battenburg.prototype.rotate_c = function(){
return new Battenburg(this.c, this.a, this.d, this.b);
}
/**
* Returns a new battenburg rotated 90 degress counter-clockwise.
*/
Battenburg.prototype.rotate_cc = function(){
return new Battenburg(this.b, this.d, this.a, this.c);
}
Battenburg.prototype.divide_by_scalar = function(div) {
return new Battenburg(this.a / div, this.b / div, this.c / div, this.d /div)
}
Battenburg.prototype.add = function(bb) {
return new Battenburg(this.a + bb.a, this.b + bb.b, this.c + bb.c, this.d + bb.d)
}
/**
* This is recursive function for calculating the
* length of the hilbert curve required to get to
* the point (x,y).
*
* The third parameter is optional - it defaults to
* the degree of precision required for doubles.
*
* The fourth parameter should not be specified -
* it defaults to the correct value. This parameter
* only exists because it is given non-default values
* during the recursion.
*
* @param {double} x - 0 <= x < 1
* @param {double} y - 0 <= y < 1
* @param {int} recursion - optional
* @param {Battenburg} curve - don't specify this
*/
function hilbert_2d_to_1d(x, y, recursion, curve) {
//console.log(x, y, recursion, curve);
if (curve === undefined) {
curve = new Battenburg(0.0, 0.25, 0.75, 0.5);
}
if (recursion === undefined) {
recursion = 28; // a good number for doubles
}
if (recursion <= 0) {
return 0.0;
}
var retv = undefined;
if (x >= 0.0 && x < 0.5 && y >= 0.0 && y < 0.5) {
retv = curve.a
+ hilbert_2d_to_1d( x*2, y*2
, recursion - 1
, curve.mirror_x().rotate_c()
) / 4;
}
if (x >= 0.5 && x < 1.0 && y >= 0.0 && y < 0.5) {
retv = curve.b
+ hilbert_2d_to_1d( (x - 0.5)*2, y*2
, recursion - 1
, curve
) / 4;
}
if (x >= 0.0 && x < 0.5 && y >= 0.5 && y < 1.0) {
retv = curve.c
+ hilbert_2d_to_1d( x*2, (y - 0.5)*2
, recursion - 1
, curve.mirror_x().rotate_cc()
) / 4;
}
if (x >= 0.5 && x < 1.0 && y >= 0.5 && y < 1.0) {
retv = curve.d
+ hilbert_2d_to_1d( (x - 0.5)*2, (y - 0.5)*2
, recursion - 1
, curve
) / 4;
}
//console.log(x, y, recursion, curve);
//console.log("retv: " + retv);
return retv;
}
function hilbert_1d_to_2d(d, recursion, curve) {
console.log(d, recursion, curve);
if (curve === undefined) {
curve = new Battenburg(0.0, 0.25, 0.75, 0.5);
}
if (recursion === undefined) {
recursion = 28; // a good number for doubles
}
if (recursion <= 0) {
return [0, 0];
}
var retv = undefined;
if (d >= curve.a && d < curve.a + 0.25) {
var d_ = (d - curve.a) * 4;
var adj = hilbert_1d_to_2d(d_, recursion - 1, curve.rotate_cc().mirror_x());
retv = [0 + adj[0]/2, 0 + adj[1]/2];
}
if (d >= curve.b && d < curve.b + 0.25) {
var d_ = (d - curve.b) * 4;
var adj = hilbert_1d_to_2d(d_, recursion - 1, curve);
retv = [0.5 + adj[0]/2, 0 + adj[1]/2];
}
if (d >= curve.c && d < curve.c + 0.25) {
var d_ = (d - curve.c) * 4;
var adj = hilbert_1d_to_2d(d_, recursion - 1, curve.rotate_c().mirror_x());
retv = [0 + adj[0]/2, 0.5 + adj[1]/2];
}
if (d >= curve.d && d < curve.d + 0.25) {
var d_ = (d - curve.d) * 4;
var adj = hilbert_1d_to_2d(d_, recursion - 1, curve);
retv = [0.5 + adj[0]/2, 0.5 + adj[1]/2];
}
console.log(d, recursion, curve);
console.log("retv: " + retv);
return retv;
}