ID:140602
 
Code:
world
map_format = ISOMETRIC_MAP
icon_size = 64

proc/Tile2Isometric(icon/i)
var/icon/isoTile = icon('Isometric.dmi',"Tile") // a 64x64 isometric tile
for(var/x = 1 to 32)for(var/y = 1 to 32)
var/dist = dist(16, 16, x, y)
if(dist)
isoTile.DrawBox(i.GetPixel(x,y), 32 + cos(arccos(16/dist) + 45), 16 + sin(arcsin(16/dist) + 45)) // Trying to rotate the icon by 45 degrees.
world<<"[32 + cos(arccos(16/dist) + 45)], [16 + sin(arcsin(16/dist) + 45)]" // Checking to see where it's placing the pixels
return isoTile

proc/dist(x1, y1, x2, y2)return sqrt((x2 - x1)^2 + (y2 - y1)^2)

mob/verb/test()
var x = 1, y = 1
for(var/r in icon_states('Tiles.dmi')) // 32x32 non-isometric tiles
var/icon/i = icon('Tiles.dmi', r)
var/obj/o = new
o.icon = Tile2Isometric(i)
o.loc = locate(x,y,1)
x++
return // This is here so I test it on one icon until I get it working so I can work quickly on making this work.
if(x > 10)
x = 1
y++
if(y > 10)
break


Problem description:
I can't get the pixels to place in the right place they all place in the same places. They all place at approximately 32,16

The only two outputs that display is "31.3385, 16.7499" and "0, 0" multiple times


Once I get this working I'm going to work on Seam Carving to shrink images while keeping the quality of the image.
Can't you just use BYOND's built in Turn() proc? Or are you trying to rotate it differently (along another axis, keep quality, etc.)?
In response to Jeff8500
It wouldn't work how I want it to when you get tiles that are 32x16 or other shapes where the width and height aren't the same. I want to be able to rotate from a specific point.
A few things I noticed:

- Use (x2-x1)*(x2-x1) instead of (x2-x1)^2, which should actually be (x2-x1)**2 (You're taking the binary XOR). It's much faster, which since you're going to be running it 32*32 times, is important. You could also make a lookup table for all of the final shifting values if you plan to run this on a large number of tiles, that way you only need to do the math once.

- 16.5 is actually the center of the tile, not 16. And 32.5 will be the center of the new 64x64 icon.

- cos() and sin() return values between -1 and 1, you need to multiply them by a radius if you want to actually go anywhere.


I haven't dove into the trig yet to check your math, but those are some places to start.
In response to DarkCampainger
DarkCampainger wrote:
A few things I noticed:

- cos() and sin() return values between -1 and 1, you need to multiply them by a radius if you want to actually go anywhere.

Thanks for the distance formula fix. I originally multiplied cos() and sin() by the distance but I was getting huge numbers so I took them out to change a few things around I must've forgotten to put them back in. my code now looks like this:
isoTile.DrawBox(i.GetPixel(x,y), 32 + cos(arccos(16/dist) + 45) * dist, 16 + sin(arcsin(16/dist) + 45) * dist)

proc/dist(x1, y1, x2, y2)return sqrt((x2 - x1)**2 + (y2 - y1)**2)


The outcome of the icon looks like this:



The transparent isometric tile you see is the default icon. The blue part is supposed to be the new icon. As you can see it's still not drawing correctly.
In response to Zaltron
Well, I have to go rake leaves, but I got it a bit closer:

world
map_format = ISOMETRIC_MAP
maxx=1
maxy=1
maxz=1
icon_size = 64

proc/Tile2Isometric(icon/i)
var/icon/isoTile = icon('Isometric.dmi',"Tile") // a 64x64 isometric tile
for(var/x = 1 to 32)
for(var/y = 1 to 32)
var
dist = dist(16.5, 16.5, x, y)
a=get_angle(x-16.5, y-16.5)+45 //arccos((x-16.5)/dist)+45
sx=round(32.5+2*dist*cos(a))
sy=round(16.5+dist*sin(a))
if(dist)
isoTile.DrawBox(i.GetPixel(x,y), sx, sy, sx+1, sy) // Trying to rotate the icon by 45 degrees.
world<<"[sx], [sy]" // Checking to see where it's placing the pixels
return isoTile

proc
dist(x1, y1, x2, y2)return sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))
get_angle(X,Y)
. = 0
if(X)
.=Y/X
. = arcsin((.)/sqrt(1+.*.))
if(X<0) .+=180
if(.<0) .+=360
else
if(Y>0) .=90
if(Y<0) .=270

mob
Login()
winset(src,"map","icon-size='64'")
..()
verb/test()
var x = 1, y = 1
for(var/r in icon_states('Tiles.dmi')) // 32x32 non-isometric tiles
var/icon/i = icon('Tiles.dmi', r)
var/obj/o = new
o.icon = Tile2Isometric(i)
o.loc = locate(x,y,1)
x++
return // This is here so I test it on one icon until I get it working so I can work quickly on making this work.
if(x > 10)
x = 1
y++
if(y > 10)
break


The scale is a little off, and it leaves some holes, but you should be able to get it working without too much effort. Remember that you're stretching it horizontally.
In response to Zaltron