Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for 0.7 #10

Merged
merged 1 commit into from
Sep 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ os:
- linux
- osx
julia:
- 0.4
- 0.5
- 0.7
- nightly
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the only real difference with #11 is that i allowed failures on nightly to make hexagons like gadfly and compose.

notifications:
email: false
Expand Down
2 changes: 1 addition & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
julia 0.4
julia 0.7
Compat 0.17
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are their any remaining calls to @compat ? if not can we remove this requirement?

90 changes: 43 additions & 47 deletions src/Hexagons.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
VERSION >= v"0.4.0-dev+6641" && __precompile__()

module Hexagons

using Compat

import Base: convert, start, next, done, length, collect
import Base: convert, length, collect, iterate

export HexagonAxial, HexagonCubic, HexagonOffsetOddR, HexagonOffsetEvenR,
hexagon, center, hexpoints, cube_round, cube_linedraw, neighbor,
Expand All @@ -19,25 +15,25 @@ export HexagonAxial, HexagonCubic, HexagonOffsetOddR, HexagonOffsetEvenR,
# Various ways to index hexagons in a grid
# ----------------------------------------

@compat abstract type Hexagon end
abstract type Hexagon end

immutable HexagonAxial <: Hexagon
struct HexagonAxial <: Hexagon
q::Int
r::Int
end

immutable HexagonCubic <: Hexagon
struct HexagonCubic <: Hexagon
x::Int
y::Int
z::Int
end

immutable HexagonOffsetOddR <: Hexagon
struct HexagonOffsetOddR <: Hexagon
q::Int
r::Int
end

immutable HexagonOffsetEvenR <: Hexagon
struct HexagonOffsetEvenR <: Hexagon
q::Int
r::Int
end
Expand Down Expand Up @@ -107,7 +103,7 @@ end
# Neighbor hexagon iterator
# -------------------------

immutable HexagonNeighborIterator
struct HexagonNeighborIterator
hex::HexagonCubic
end

Expand All @@ -123,22 +119,21 @@ const CUBIC_HEX_NEIGHBOR_OFFSETS = [
neighbors(hex::Hexagon) = HexagonNeighborIterator(convert(HexagonCubic, hex))

length(::HexagonNeighborIterator) = 6
start(::HexagonNeighborIterator) = 1
done(::HexagonNeighborIterator, state::Int) = state > 6

function next(it::HexagonNeighborIterator, state::Int)
function Base.iterate(it::HexagonNeighborIterator, state=1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here and elsewhere, must one qualify iterate with Base. ?

state > 6 && return nothing
dx = CUBIC_HEX_NEIGHBOR_OFFSETS[state, 1]
dy = CUBIC_HEX_NEIGHBOR_OFFSETS[state, 2]
dz = CUBIC_HEX_NEIGHBOR_OFFSETS[state, 3]
neighbor = HexagonCubic(it.hex.x + dx, it.hex.y + dy, it.hex.z + dz)
return (neighbor, state+1)
return (neighbor, state + 1)
end


# Diagonal hexagon iterator
# -------------------------

immutable HexagonDiagonalIterator
struct HexagonDiagonalIterator
hex::HexagonCubic
end

Expand All @@ -154,37 +149,36 @@ const CUBIC_HEX_DIAGONAL_OFFSETS = [
diagonals(hex::Hexagon) = HexagonDiagonalIterator(convert(HexagonCubic, hex))

length(::HexagonDiagonalIterator) = 6
start(::HexagonDiagonalIterator) = 1
done(::HexagonDiagonalIterator, state::Int) = state > 6

function next(it::HexagonDiagonalIterator, state::Int)
function Base.iterate(it::HexagonDiagonalIterator, state=1)
state > 6 && return nothing
dx = CUBIC_HEX_DIAGONAL_OFFSETS[state, 1]
dy = CUBIC_HEX_DIAGONAL_OFFSETS[state, 2]
dz = CUBIC_HEX_DIAGONAL_OFFSETS[state, 3]
diagonal = HexagonCubic(it.hex.x + dx, it.hex.y + dy, it.hex.z + dz)
return (diagonal, state+1)
return (diagonal, state + 1)
end


# Iterator over the vertices of a hexagon
# ---------------------------------------

immutable HexagonVertexIterator
struct HexagonVertexIterator
x_center::Float64
y_center::Float64
xsize::Float64
ysize::Float64

function HexagonVertexIterator(x, y, xsize=1.0, ysize=1.0)
new((@compat Float64(x)), (@compat Float64(y)),
(@compat Float64(xsize)), (@compat Float64(ysize)))
new((Float64(x)), (Float64(y)),
(Float64(xsize)), (Float64(ysize)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here and elsewhere, there are extra parens that could be removed

end

function HexagonVertexIterator(hex::Hexagon,
xsize=1.0, ysize=1.0, xoff=0.0, yoff=0.0)
c = center(hex, xsize, ysize, xoff, yoff)
new((@compat Float64(c[1])), (@compat Float64(c[2])),
(@compat Float64(xsize)), (@compat Float64(ysize)))
new((Float64(c[1])), (Float64(c[2])),
(Float64(xsize)), (Float64(ysize)))
end
end

Expand All @@ -195,23 +189,23 @@ end

# TODO: remove this function?
function hexpoints(x, y, xsize=1.0, ysize=1.0)
collect((@compat Tuple{Float64, Float64}),
HexagonVertexIterator((@compat Float64(x)), (@compat Float64(y)),
(@compat Float64(xsize)), (@compat Float64(ysize))))
collect((Tuple{Float64, Float64}),
HexagonVertexIterator((Float64(x)), (Float64(y)),
(Float64(xsize)), (Float64(ysize))))
end

length(::HexagonVertexIterator) = 6
start(::HexagonVertexIterator) = 1
done(::HexagonVertexIterator, state::Int) = state > 6

function next(it::HexagonVertexIterator, state)
function Base.iterate(it::HexagonVertexIterator, state=1)
state > 6 && return nothing
theta = 2*pi/6 * (state-1+0.5)
x_i = it.x_center + it.xsize * cos(theta)
y_i = it.y_center + it.ysize * sin(theta)
return ((x_i, y_i), state+1)
return ((x_i, y_i), state + 1)
end

immutable HexagonDistanceIterator

struct HexagonDistanceIterator
hex::HexagonCubic
n::Int
end
Expand All @@ -223,11 +217,10 @@ end
hexagons_within(hex::Hexagon, n::Int) = hexagons_within(n, hex)

length(it::HexagonDistanceIterator) = it.n * (it.n + 1) * 3 + 1
start(it::HexagonDistanceIterator) = (-it.n, 0)
done(it::HexagonDistanceIterator, state::(@compat Tuple{Int, Int})) = (state[1] > it.n)

function next(it::HexagonDistanceIterator, state::(@compat Tuple{Int,Int}))
function Base.iterate(it::HexagonDistanceIterator, state=(-it.n, 0))
x, y = state
x > it.n && return nothing
z = -x-y
hex = HexagonCubic(x, y, z)
y += 1
Expand All @@ -238,12 +231,13 @@ function next(it::HexagonDistanceIterator, state::(@compat Tuple{Int,Int}))
hex, (x, y)
end


collect(it::HexagonDistanceIterator) = collect(HexagonCubic, it)

# Iterator over a ring of hexagons
# ---------------------------------------

immutable HexagonRingIterator
struct HexagonRingIterator
hex::HexagonCubic
n::Int
end
Expand All @@ -256,11 +250,11 @@ end
ring(hex::Hexagon, n::Int) = ring(n, hex)

length(it::HexagonRingIterator) = it.n * 6
start(it::HexagonRingIterator) = (1, neighbor(it.hex, 5, it.n))
done(it::HexagonRingIterator, state::(@compat Tuple{Int, HexagonCubic})) = state[1] > length(it)

function next(it::HexagonRingIterator, state::(@compat Tuple{Int, HexagonCubic}))
function Base.iterate(it::HexagonRingIterator,
state::(Tuple{Int, HexagonCubic})=(1, neighbor(it.hex, 5, it.n)))
hex_i, cur_hex = state
hex_i > length(it) && return nothing
# println("HexagonRingIterator: at position $hex_i ($cur_hex)")
ring_part = div(hex_i - 1, it.n) + 1
next_hex = neighbor(cur_hex, ring_part)
Expand All @@ -272,12 +266,12 @@ collect(it::HexagonRingIterator) = collect(HexagonCubic, it)
# Iterator over all hexes within a certain distance
# -------------------------------------------------

immutable HexagonSpiralIterator
struct HexagonSpiralIterator
hex::HexagonCubic
n::Int
end

immutable HexagonSpiralIteratorState
struct HexagonSpiralIteratorState
hexring_i::Int
hexring_it::HexagonRingIterator
hexring_it_i::Int
Expand All @@ -291,17 +285,18 @@ end
spiral(hex::Hexagon, n::Int) = spiral(n, hex)

length(it::HexagonSpiralIterator) = it.n * (it.n + 1) * 3
function start(it::HexagonSpiralIterator)
function _start(it::HexagonSpiralIterator)
first_ring = ring(it.hex, 1)
HexagonSpiralIteratorState(1, first_ring, start(first_ring)...)
end
done(it::HexagonSpiralIterator, state::HexagonSpiralIteratorState) = state.hexring_i > it.n

# The state of a HexagonSpiralIterator consists of
# 1. an Int, the index of the current ring
# 2. a HexagonRingIterator and its state to keep track of the current position
# in the ring.
function next(it::HexagonSpiralIterator, state::HexagonSpiralIteratorState)
function Base.iterate(it::HexagonSpiralIterator,
state::HexagonSpiralIteratorState=_start(it))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are their pros and cons to calling _start in the function signature, versus creating a second iterate method with a single input argument as i did in #11 ? the latter is easier to read to me, but i'm not familiar enough with julia internals to know if there's a performance difference.

state.hexring_i > it.n && return nothing
# Get current state
hexring_i, hexring_it, hexring_it_i, hexring_it_hex =
state.hexring_i, state.hexring_it, state.hexring_it_i, state.hexring_it_hex
Expand All @@ -317,7 +312,8 @@ function next(it::HexagonSpiralIterator, state::HexagonSpiralIteratorState)
end

# println("Currently at $hexring_it_hex, hexring is $hexring_it, state is $((hexring_i, (hexring_it_i, hexring_it_hex)))")
hexring_it_hex, HexagonSpiralIteratorState(hexring_i, hexring_it, hexring_it_i, hexring_it_hex_next)
hexring_it_hex, HexagonSpiralIteratorState(hexring_i, hexring_it,
hexring_it_i, hexring_it_hex_next)
end

collect(it::HexagonSpiralIterator) = collect(HexagonCubic, it)
Expand Down Expand Up @@ -357,7 +353,7 @@ end

# Find the nearest hexagon in cubic coordinates.
function nearest_cubic_hexagon(x::Real, y::Real, z::Real)
rx, ry, rz = @compat round(Integer, x), round(Integer, y), round(Integer, z)
rx, ry, rz = round(Integer, x), round(Integer, y), round(Integer, z)
x_diff, y_diff, z_diff = abs(rx - x), abs(ry - y), abs(rz - z)

if x_diff > y_diff && x_diff > z_diff
Expand Down
2 changes: 1 addition & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Hexagons
using Base.Test
using Test

convert(HexagonOffsetOddR, HexagonAxial(2, 4))

Expand Down