ASCII Isometric Graphics...

C

CBlair1986

Hello, all.

I've just got a bit of a question, here. I suppose my mind's a bit too
tired to think of a solution at the moment, but it's been on my mind
for a while. What I'd like to do is take an array and turn it into an
isometric view of the data, eg:

[[[1,1], # Bottom Layer
[1,1]],
[[0,1], # Top Layer
[0,0]]]

to
+-----+
|\ \
| +-----+
+-----+ | |
|\ \| |
| +-----+-----+
+ |\ \ \
\| +-----+-----+
+ | | |
\| | |
+-----+-----+

The array would hold only binary data, either 1/0 or true/false.

Any help will be greatly appreciated!
 
M

Markus Koenig

CBlair1986 said:
I've just got a bit of a question, here. I suppose my mind's a bit too
tired to think of a solution at the moment, but it's been on my mind
for a while. What I'd like to do is take an array and turn it into an
isometric view of the data, eg:

[...]

Heh, another Ruby quiz. ;)


class Array
def isowidth
first.first.length
end

def isodepth
first.length
end

alias isoheight length

# returns a isometric representation as a String
# give the value representing "true" as a parameter
def isometric(truevalue = true)
# build the graphic lines
ascii_width = isowidth * 6 + isodepth * 2 + 1
ascii_height = isoheight * 3 + isodepth * 2 + 1
ascii = Array.new(ascii_height) {
" " * ascii_width
}

# traverse all bricks
0.upto(isoheight-1) do |y|
0.upto(isodepth-1) do |z|
(isowidth-1).downto(0) do |x|
# only draw certain bricks
next if self[y][z][x] != truevalue

# calculate the coordinates
xa = x * 6 + z * 2
ya = (isoheight-y-1) * 3 + z * 2

# "draw" the brick
ascii[ya][xa, 7] = '+-----+'
ascii[ya+1][xa, 8] = '|\\ \\'
ascii[ya+2][xa, 9] = '| +-----+'
ascii[ya+3][xa, 9] = '+ | |'
ascii[ya+4][xa+1, 8] = '\\| |'
ascii[ya+5][xa+2, 7] = '+-----+'
end
end
end

# join the lines
return ascii.join("\n")
end
end


data = [[[1, 1],
[1, 1]],
[[0, 1],
[0, 0]]]

puts data.isometric(1)


Have fun,
Markus
 
J

Jacob Fugal

Hello, all.

I've just got a bit of a question, here. I suppose my mind's a bit too
tired to think of a solution at the moment, but it's been on my mind
for a while. What I'd like to do is take an array and turn it into an
isometric view of the data, eg:

[[[1,1], # Bottom Layer
[1,1]],
[[0,1], # Top Layer
[0,0]]]

to
+-----+
|\ \
| +-----+
+-----+ | |
|\ \| |
| +-----+-----+
+ |\ \ \
\| +-----+-----+
+ | | |
\| | |
+-----+-----+

The array would hold only binary data, either 1/0 or true/false.

Rather than accomadating 1/0 or true/false, I just did 1/0. Handling
both is harder than you think, given that 0 is true.

# --------------------
class Canvas
def draw( data, x=3D0, y=3D0 )
layers =3D data.size
rows =3D data.map{ |layer| layer.size }.max
columns =3D data.map{ |layer|
layer.map{ |row| row.size }.max
}.max

@canvas =3D []
(layers * 3 + rows * 2 + 1).times do |i|
@canvas =3D ([' '] * (columns * 6 * rows * 2 + 1)).join
end

@x, @y =3D x, y

@y +=3D data.size * 3
data.each do |layer|
@y -=3D 3
draw_layer( layer )
end

puts @canvas.join("\n")
end

def draw_layer( layer )
layer.each do |row|
draw_row( row )
@x +=3D 2
@y +=3D 2
end
@x -=3D layer.size * 2
@y -=3D layer.size * 2
end

def draw_row( row )
@x +=3D row.size * 6
row.reverse.each do |datum|
@x -=3D 6
draw_box unless datum.zero?
end
end

def draw_box
@canvas[@y + 0][(@x + 0)..(@x + 6)] =3D '+-----+'
@canvas[@y + 1][(@x + 0)..(@x + 7)] =3D '|\\ \\'
@canvas[@y + 2][(@x + 0)..(@x + 8)] =3D '| +-----+'
@canvas[@y + 3][(@x + 0)..(@x + 8)] =3D '+ | |'
@canvas[@y + 4][(@x + 1)..(@x + 8)] =3D '\\| |'
@canvas[@y + 5][(@x + 2)..(@x + 8)] =3D '+-----+'
end
end

data =3D [[[ 1, 1 ],
[ 1, 1 ]],
[[ 0, 1 ],
[ 0, 0 ]]]

Canvas.new.draw( data )
 
J

Jacob Fugal

Heh, we got pretty similar solutions there, Markus. Great minds... ? :)

Jacob Fugal
 
D

Dominik Bathon

CBlair1986 said:
I've just got a bit of a question, here. I suppose my mind's a bit too
tired to think of a solution at the moment, but it's been on my mind
for a while. What I'd like to do is take an array and turn it into an
isometric view of the data, eg:

[...]

Heh, another Ruby quiz. ;)

Indeed, here is my solution:


class AsciiCanvas

def initialize
@dat =3D []
end

def to_s
@dat.join("\n")
end

def draw(str, x, y)
lines =3D str.split("\n")
lines.each_with_index { |l, i|
cy =3D y + i
cl =3D (@dat[cy] || "")
cl =3D cl.ljust(x+l.size)
cl[x, l.size] =3D l
@dat[cy] =3D cl
}
end

end

def make_iso_view(array)
square =3D "+-----+\n| |\n| |\n+-----+"
con =3D "\\ \\\n \n \n\\"

a =3D AsciiCanvas.new
stepx =3D 6
stepy =3D 3
stepz =3D 2

# draw from bottom to top, back to front and right to left
y =3D stepy * (array.size - 1)
array.each { |level|
ly, lx =3D y, 0
level.each { |row|
ry, rx =3D ly, lx + stepx * (row.size - 1)
row.reverse.each { |box|
unless !box || box =3D=3D 0
a.draw(square, rx, ry)
a.draw(con, rx+1, ry+1)
a.draw(square, rx+2, ry+2)
end
rx -=3D stepx
}
lx +=3D stepz
ly +=3D stepz
}
y -=3D stepy
}
a.to_s
end

if $0 =3D=3D __FILE__
puts make_iso_view([[[1,1], [1,1]], [[0,1], [0,0]]])
puts make_iso_view([[[0,1,1], [1,0,1]], [[0,1,0], [0,0,0]]])
end


Dominik
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,184
Messages
2,570,978
Members
47,561
Latest member
gjsign

Latest Threads

Top