ID:1657554
 
Keywords: rotation
(See the best response by FKI.)
Problem
Okay so in my current project i have turfs setup in rectangles with two main points one on the bottom right and the other on the top left. What I want to do is to copy the rectangle say a 3x5 rotate it by 90 degrees so its a 5x3 and pass that somewhere else

Picture form

Turn this rectangle into
.__
|....|
|....|
|__|

This rectangle(but the same size) and move it to a new location
_____
|.........|
|_____|
Best response
Have you heard of and tried applying the matrix type?
I don't think that works from what i understand matrices apply to individual atom unless theirs a way to translate them to a list and manipulate them like that. Which is sorta what i need sorry i am a noob when it comes matrix mathematics and i am not the best coder so it makes them hard to use. If you know how to do this please share, it would help out a bunch. Sorry i am not providing code its just i have no clue where to start.
In response to Zelda123
mob/verb/turn_me()
var/matrix/m = new()

m.Turn(pick(90, -90))

// apply the transformation to the mob.
src.transform = m


?
Well, I don't know if I understand your question exactly, but if you're asking how to get a block of turf objects and move them as if rotating, such as turning a house so that say there's a door to the north, turning it 90 degrees would result in the door being on the east I've actually played around with that a bit.

When messing with such things I for one like to play around with saving turf to an icon by creating a code of sorts which can translate a turf type to a color and back again, then just saving a block of turf to an icon, rotating the icon, and then using get_pixel() to get the colors to translate into what new turf to create and where. The fact that icons and maps both follow a simple grid system makes this a useful method for manipulating map generators of all kinds.

There's probably also a more direct method of simply manipulating their location on a grid to determine where to create the new copy by applying some mathematical formula that I don't quite have the time to figure out but I'm quite certain exists.

Either way, the 'block()' proc probably could aid you.
Response to FKI
That's not what i am looking for thanks however. What that does is rotation for an individual atom if i do it like that it would rotate the individual pictures and do nothing to the overall structure which is the real thing i am trying to do Thanks still you gave a nice reply

Response to Felix
You are right in what i want to do but i cant just put in into an icon editor and rotate because i need a dynamic chunk not just an big icon i use. I could do it by hand but there going to over 100 rooms with 4 rotations each.

However thanks for the block() proc i through one together but that is way more efficient than mine.

To anyone else
If you know a how to do this please your help is appreciated. You don't have to code it but if you could point me in the right direction it would much appreciated.
In response to Zelda123
Zelda123 wrote:
Response to Felix
You are right in what i want to do but i cant just put in into an icon editor and rotate because i need a dynamic chunk not just an big icon i use. I could do it by hand but there going to over 100 rooms with 4 rotations each.

That's not what I mean really. Quite simply an icon and a map are very similar, the bottom left pixel of an icon could be compared to the bottom left of a section of map. To achieve what you want to accomplish you need to think grids. As such, one can for example, one could say that the color "#ffffff" represents a wall, while "#000000" represents a floor, and null (alpha in an icon) represents nothing. You could then draw an icon with a 3x3 box of #000000 with a single pixel of #ffffff in the middle to represent a walled in room with a single floor in the middle of it.

One can then say something like this:
proc/Apply_Structure(XX,YY,ZZ)
var/icon/I = icon('The Described Icon.dmi')
for(var/X = 1 to I.Width()) for(var/Y = 1 to I.Height())
var/pixel=I.get_pixel(X,Y)
var/LOC=locate(XX+X-1,YY+Y-1,ZZ)
if(LOC) switch(pixel)
if(null) continue
if("#ffffff") new/turf/floor(LOC)
if("#000000") new/turf/wall(LOC)

The above process would create our described room with the bottom left of the room at the specified X,Y,Z coords by reading the described icon's pixel colors and translating them into what kind of turf to create at the relative x and y location.

Now, we can also write the other way around to write turf tiles to an icon so we can read the icon to create the new turf tiles.
proc/Write_Turf(turf/A,turf/B)
var/list/BLOCK=block(A,B)
var/Sub_X=A.x-1
var/Sub_Y=A.y-1
var/icon/I = new('1x1 Alpha Icon.dmi')
I.Scale(B.x-A.x,B.y-A.y)
for(var/turf/t in BLOCK)
I.DrawBox(t.SAVE_COLOR,t.x-Sub_X,t.y-Sub_y)

Outside the above process we would set the var used:
turf/var/SAVE_COLOR
turf/wall/SAVE_COLOR="#000000"
turf/floor/SAVE_COLOR="#ffffff"

With all that information in mind, the above proc could save a block of turf tiles into an icon, and be read back in another location using the block of code listed above the above block of code.

Do note all the code here isn't tested and may contain a few typos or calculation errors on my part, but hopefully it's obvious enough to explain exactly how this can accomplish what you're looking for. And if you don't get it, don't worry, as I'm renown for being bad at explaining things!

Also note this is just a method I came up with, and might not actually be the best way of doing things, it's just how I have done it in the past.
In response to Zelda123
Either you would want to combine the original icons into a single icon (using merge) and turn, or you would want to flip and recalculate the positions.

There isn't something that would do the second for you.