Simplified code. Add/substract min value when interleaving. BigMin still broken.

This commit is contained in:
Sascha L. Teichmann 2014-09-07 09:58:09 +02:00
parent 6e958e4ff6
commit a8c2a4c55d
2 changed files with 29 additions and 21 deletions

View File

@ -14,6 +14,8 @@ const (
numBitsPerComponent = 12 numBitsPerComponent = 12
modulo = 1 << numBitsPerComponent modulo = 1 << numBitsPerComponent
maxPositive = modulo / 2 maxPositive = modulo / 2
minValue = -1 << numBitsPerComponent
maxValue = 1<<numBitsPerComponent - 1
) )
type ( type (
@ -43,10 +45,6 @@ func (c Coord) String() string {
return fmt.Sprintf("(%d, %d, %d)", c.X, c.Y, c.Z) return fmt.Sprintf("(%d, %d, %d)", c.X, c.Y, c.Z)
} }
func (c Coord) Equals(o Coord) bool {
return c.X == o.X && c.Y == o.Y && c.Z == o.Z
}
func minComponent(a, b int16) int16 { func minComponent(a, b int16) int16 {
if a < b { if a < b {
return a return a
@ -109,17 +107,20 @@ func DecodeFromBigEndian(key []byte) (int64, error) {
func CoordToInterleaved(c Coord) (result int64) { func CoordToInterleaved(c Coord) (result int64) {
const end = 1 << (numBitsPerComponent + 1) const end = 1 << (numBitsPerComponent + 1)
x := uint16(c.X - minValue)
y := uint16(c.Y - minValue)
z := uint16(c.Z - minValue)
setmask := int64(1) setmask := int64(1)
for mask := int16(1); mask != end; mask <<= 1 { for mask := uint16(1); mask != end; mask <<= 1 {
if c.X&mask != 0 { if x&mask != 0 {
result |= setmask result |= setmask
} }
setmask <<= 1 setmask <<= 1
if c.Y&mask != 0 { if y&mask != 0 {
result |= setmask result |= setmask
} }
setmask <<= 1 setmask <<= 1
if c.Z&mask != 0 { if z&mask != 0 {
result |= setmask result |= setmask
} }
setmask <<= 1 setmask <<= 1
@ -144,15 +145,9 @@ func InterleavedToCoord(pos int64) Coord {
} }
pos >>= 1 pos >>= 1
} }
if x >= 1<<numBitsPerComponent { x += minValue
x -= end y += minValue
} z += minValue
if y >= 1<<numBitsPerComponent {
y -= end
}
if z >= 1<<numBitsPerComponent {
z -= end
}
return Coord{X: x, Y: y, Z: z} return Coord{X: x, Y: y, Z: z}
} }
@ -250,8 +245,7 @@ func NaiveBigMin(minz, maxz, zcode int64) int64 {
} }
const ( const (
bits = 12 msb = uint8(3*numBitsPerComponent - 1)
msb = uint8(3*bits - 1)
mask = int64(0x924924924) mask = int64(0x924924924)
full = int64(0xfffffffff) full = int64(0xfffffffff)
) )

View File

@ -87,7 +87,7 @@ func checkJoinSplit(
k := join(c) k := join(c)
s := split(k) s := split(k)
if !s.Equals(c) { if s != c {
t.Errorf("%s: Expected %s got %s %b\n", desc, c, s, k) t.Errorf("%s: Expected %s got %s %b\n", desc, c, s, k)
} }
} }
@ -153,6 +153,15 @@ func TestTransforms(t *testing.T) {
}) })
} }
func TestCoordInterleaving(t *testing.T) {
allData(func(c Coord) {
d := InterleavedToCoord(CoordToInterleaved(c))
if c != d {
t.Errorf("Expected %v got %v\n", c, d)
}
})
}
func outsiders(zmin, zmax int64) chan int64 { func outsiders(zmin, zmax int64) chan int64 {
outs := make(chan int64) outs := make(chan int64)
@ -200,6 +209,10 @@ func TestBigMin(t *testing.T) {
zmin := CoordToInterleaved(c1) zmin := CoordToInterleaved(c1)
zmax := CoordToInterleaved(c2) zmax := CoordToInterleaved(c2)
if zmin > zmax {
t.Errorf("zmin > zmax: %d > %d\n", zmin, zmax)
}
errors, success := 0, 0 errors, success := 0, 0
for zcode := range outsiders(zmin, zmax) { for zcode := range outsiders(zmin, zmax) {
nbm := NaiveBigMin(zmin, zmax, zcode) nbm := NaiveBigMin(zmin, zmax, zcode)
@ -214,8 +227,9 @@ func TestBigMin(t *testing.T) {
} }
if errors > 0 { if errors > 0 {
cub := Cuboid{P1: c1, P2: c2} cub := Cuboid{P1: c1, P2: c2}
t.Errorf("BigMin: %s %d errors out of %d (%f)\n", t.Errorf("BigMin: %s (%d %d) %d errors out of %d (%f)\n",
cub, cub,
zmin, zmax,
errors, errors+success, errors, errors+success,
float64(errors)/float64(errors+success)) float64(errors)/float64(errors+success))
} }