Marching squares: Difference between revisions

m (→‎{{header|Julia}}: add plotting)
Line 37:
<pre>
points = [(3, 4), (4, 3), (4, 2), (4, 1), (3, 0), (2, 1), (2, 1), (1, 2), (1, 3), (2, 4), (3, 4)]
</pre>
 
 
=={{header|Lua}}==
Based on the Phix and Wren solutions.
<lang Lua>-- positive directions: right, down, clockwise
local Directions = { -- clockwise from North
N = {x= 0, y=-1},
E = {x= 1, y= 0},
S = {x= 0, y= 1},
W = {x=-1, y= 0},
}
 
local dxdybList = {
{0,0,1}, -- same position
{1,0,2}, -- right
{0,1,4}, -- down
{1,1,8}, -- right and down
}
 
local cases = {
"W", "N", "W", "S",
"S", nil, "S", "E",
nil, "N", "W", "E",
"E", "N",
}
 
local function identifyPerimeter(iLayer, startingX, startingY, data)
local resultDirections = {}
local resultPositions = {}
local currentX, currentY = startingX, startingY
local direction, prevDirection
while true do
local mask = 0
for _, d in ipairs (dxdybList) do
local dx, dy, b = d[1], d[2], d[3]
local mx, my = currentX+dx, currentY+dy
if mx>1 and my>1
and data[my-1] and data[my-1][mx-1]
and data[my-1][mx-1] == iLayer then
mask = mask + b
end
end
direction = cases[mask]
if not direction then
if mask == 6 then
direction = (prevDirection == "E") and "N" or "S"
elseif mask == 9 then
direction = (prevDirection == "S") and "E" or "W"
else
error ('no mask: '.. mask..' by x:'..currentX..' y:'..currentY, 1)
end
end
table.insert (resultDirections, direction)
table.insert (resultPositions, currentX)
table.insert (resultPositions, currentY)
local vDir = Directions[direction]
currentX, currentY = currentX+vDir.x, currentY+vDir.y
prevDirection = direction
if startingX == currentX and startingY == currentY then
return resultDirections, resultPositions
end
end
end
 
local function findFirstOnLayer (iLayer, data)
for y = 1, #data do -- from 1 to hight
for x = 1, #data[1] do -- from 1 to width
local value = data[y][x]
if value == iLayer then
return x, y -- only one contour
end
end
end
end
 
local function msMain (iLayer, data)
local rootX, rootY = findFirstOnLayer (iLayer, data)
print ("root: x="..rootX..' y='..rootY)
local directions, positions = identifyPerimeter(iLayer, rootX, rootY, data)
print ('directions amount: '..#directions)
print ('directions: '.. table.concat (directions, ','))
local strPositions = ""
for i = 1, #positions-1, 2 do
strPositions = strPositions..positions[i]..','..positions[i+1]..', '
end
print ('positions: {' .. strPositions..'}')
end
 
local example = {
{0, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 1},
{0, 1, 1, 0, 1, 0},
{0, 1, 1, 1, 1, 0},
{0, 1, 0, 1, 1, 0},
{1, 0, 0, 0, 0, 1},
}
 
msMain (1, example)
</lang>{{out}}
<pre>
root: x=1 y=2
directions amount: 34
directions: E,S,E,E,S,E,N,E,N,E,S,W,S,S,S,E,S,W,N,W,W,N,W,S,W,S,W,N,E,N,N,N,W,N
positions: {1,2, 2,2, 2,3, 3,3, 4,3, 4,4, 5,4, 5,3, 6,3, 6,2, 7,2, 7,3, 6,3, 6,4, 6,5, 6,6, 7,6, 7,7, 6,7, 6,6, 5,6, 4,6, 4,5, 3,5, 3,6, 2,6, 2,7, 1,7, 1,6, 2,6, 2,5, 2,4, 2,3, 1,3, }
</pre>
 
Anonymous user