Hawaiian Islands From Space
Sun 10 December 2017Hawaiian Islands Topography in Minecraft¶
Taking this a step further, I edited a topography map of the islands to make the ocean blue and resized it smaller, which you can see below:
This program essentially works the same as the image drawing program, but the brick array is organized by height and the RGB comparison array is based on the colors in the topo map. Also, instead of drawing individual bricks, it draws a line of bricks extending from the origin to the value of the RGB array (which is also used as the index of the brick array).
Here is my commented Python script for the topography map:
#image processing library for image processing
from PIL import Image
#math library for square root
import math
#set variable im to read image
im = Image.open('mc/hawaii-nc.jpg', 'r')
#set pix_val to array of (R, B, G) from im
pix_val = list(im.getdata())
#color_array is based on (R, G, B) values to match the map image file
#the 4th tuple in color_array is the index for minecraft script's block_array as well as the relative height (variable value in topo.js)
#blue(ocean)0, white(sand)1, dark green (lowlands)2, medium green3, lighter green 4, lightest green 5, light yellow 6, orange 7, dark orange 8, dark red orange 9, dark red 10, black 11
color_array = [(0, 0, 255, 0), (255, 255, 255, 1), (0, 102, 0, 2), (51, 153, 51, 3), (0, 204, 0, 4), (0, 255, 0, 5), (255, 255, 102, 6), (255, 204, 0, 7), (255, 153, 51, 8), (255, 102, 0, 9), (153, 0, 0, 10), (0, 0, 0, 11)]
pix_array = []
#iterate through pix_val and choose the best color by least difference for each pixel
for pixel in pix_val:
#initialize current_best at an arbitrarily high value
current_best = 1000
#iterate through all colors in the array comparing the difference between color array items and the current pixel's RGB values
for color in color_array:
#distance is sqrt((R-r)^2+(B-b)^2+(G-g)^2)
distance = math.sqrt((color[0] - pixel[0])**2 + (color[1] - pixel[1])**2 + (color[2] - pixel[2])**2)
#set current_best to best_color if the distance is less than the current_best
if distance < current_best:
current_best = distance
best_color = color[3]
#add current best_color to the output array
pix_array.append(best_color)
#print output array
print(pix_array[:100])
You can see how much water (0) there will be in the final rendering!
Here is the MakeCode JavaScript (sans the pixlist which crashed even the web editor several times... paste your terminal output and code in a text editor and paste the whole thing into a fresh web editor instance):
let block_type = 0
let pixlist: number[] = []
let color_array: number[] = []
let y = 0
let x = 0
player.onChat("run", function () {
x = 0
y = -10
color_array = [blocks.block(Block.Water), blocks.block(Block.Sand), blocks.block(Block.Sand), blocks.block(Block.Grass), blocks.block(Block.Grass), blocks.block(Block.Dirt), blocks.block(Block.RedSand), blocks.block(Block.RedSand), blocks.block(Block.RedSand), blocks.block(Block.Stone), blocks.block(Block.Stone), blocks.block(Block.Snow)]
pixlist = []
for (let value of pixlist) {
block_type = color_array[value]
shapes.line(block_type, positions.create(x, 0, y), positions.create(x, value, y))
if (344 < x) {
x = 0
y += -1
player.say("line" + y.toString())
} x += 1
}
})
One issue I ran into with this is that at about x 280 y -200 the bricks were too far away from my character. After I explored the area I ran the script for only that section (if x > 200 && y < -200) {draw stuff} and it filled in the missing part of the Big Island. I think a better way, as opposed to standing in one corner as I did here, would be to have the character in the center and start the drawing at -width/2 and +height/2. This would potentially increase the usable area by 4 times.
Here are some more pictures of the Hawaiian islands topography: