Scripting Helpers is winding down operations and is now read-only. More info→
Log in to vote

Transforming 2D point to 2D object-space [closed]

Asked by
MrNicNac 855 Moderation Voter
10 years ago

I have a plugin, GUI Studio, and I want to add support for rotated GUIs. Right now, I'm trying to position pseudo-resize handles (just other GUIs) on the left/top/bottom/right sides of the GUI no matter it's rotation.

I will present the Left handle code. The issue I am having is that it is slightly below the center of the left side (imagine the left side of a GUI and it rotated and now imagine where you could see a resize-handle at the center of that side). It's not there, and always ends up slightly below the correct point.

Here is how I find the direction from the rotation

function GetGuiDirection(x, gui)
    local rotation;
    if x == "Left" then
        rotation = math.rad(gui.Rotation+270)
    elseif x == "Top" then
        rotation = math.rad(gui.Rotation)
    elseif x == "Right" then
        rotation = math.rad(gui.Rotation+90)
    elseif x == "Bottom" then
        rotation = math.rad(180+gui.Rotation)
    return, (math.cos(rotation)))

And here is how I am positioning the LEFT resize handle:

local left_direction = GetGuiDirection("Left", gui_x)

local solvedx = ((posx+sizex/2)-rhandle.AbsoluteSize.X) + ((sizex/2) * left_direction.x)
local solvedy = ((posy+sizey/2)-rhandle.AbsoluteSize.Y/2) - ((sizex/2) * left_direction.y)
print(((posy+sizey/2)-rhandle.AbsoluteSize.Y/2), " - ", ((sizex/2) * left_direction.y))

left.Position =,solvedx,0,solvedy);

Just notice that the math in the first set of parenthesis on the solve_ variables is just to get the center of whatever GUI is currently selected. In general, everything is correct and it gets positioned in the same relative-coordinates no matter the rotation/size. It's just that it is slightly below (on the Y axis) where it should be.

Does anyone have any experience with this sort of math and can explain a solution - or the problem?

Locked by Thewsomeguy and Articulating

This question has been locked to preserve its current state and prevent spam and unwanted comments and answers.

Why was this question closed?

1 answer

Log in to vote
Answered by
blocco 185
10 years ago

GUI objects in ROBLOX are positioned based on their top-left coordinates when they're not rotated, and they're rotated based on their center coordinates. This can cause some problems when figuring out where things are rendered.

Center Coordinates

Since GUI objects are rotated around their center coordinates, I decided to make a function that told me where the center coordinates are:

local function GetCenterOfGuiObject(guiObject)
        guiObject.AbsolutePosition.x + guiObject.AbsoluteSize.x/2,
        guiObject.AbsolutePosition.y + guiObject.AbsoluteSize.y/2

Center of Edges

Having this function, we can now focus on finding the centers of the edges, which we can then use to determine the placements of the handles. Things to note:

  • The rotations go clockwise instead of the natural counterclockwise.
  • The y axis is flipped; as you go down, the y-ordinate gets bigger instead of smaller.
  • As a GUI object rotates, the center of each edge stays the same distance away from the center of the GUI object; the center of each edge draws a circle around the GUI object as it moves.

Keeping these things in mind, I wrote a simple function to help me determine where the edges of any GUI object would be:

local function GetCenterOfEdge(guiObject, edge)
    local center = GetCenterOfGuiObject(guiObject);
    local size = guiObject.AbsoluteSize;
    local rotation = math.rad(guiObject.Rotation);
    if edge == "Left" then
        size =, size.x) -- moves like a circle
        rotation = rotation - math.pi;
    elseif edge == "Top" then
        size =, size.y)
        rotation = rotation - math.pi/2;
    elseif edge == "Right" then
        size =, size.x)
        rotation = rotation;
    elseif edge == "Bottom" then
        size =, size.y)
        rotation = rotation + math.pi/2;
    rotation = -rotation; -- clockwise
    return center + (size/2) *
        -math.sin(rotation) -- to fix flipped y-axis

Now that we know the centers of any edge, we can easily position the top-left of our handles relative to that. I'm sure you can figure out how to do that, however. :P

The results I'm getting are not very close to the center of any of the edges using your code. With the Y value being the most "off." MrNicNac 855 — 10y
My bad. The X coordinate seems rather fine (mine was as well); but, again like mine, the Y coordinate is very off. MrNicNac 855 — 10y
How are you using my code? I'm getting the center of the edge each time I call the function. blocco 185 — 10y
0,centerofedge.x-rhandle.AbsoluteSize.X/2,0,centerofedge.y-rhandle.AbsoluteSize.Y/2); -> As the GUI's size increases, the accuracy of the Y coordinate decreases. What factor am I missing? MrNicNac 855 — 10y
View all comments (13 more)
Ah yes... I was testing my code on a square. I should have tested it on a rectangle. I see what's going on. I'll try to figure it out. blocco 185 — 10y
I have fixed it, and edited my answer accordingly. blocco 185 — 10y
Heh....I still regret to say that I am getting the _exact_ same result as my code gave me. The position of the handle (I am testing the left face) is still slightly below where it show be. Could this be a rounding error or something similar? MrNicNac 855 — 10y
Here ( is an image of what is happening (only pay attention to the left-side handle at the moment) MrNicNac 855 — 10y
Is your image centered? blocco 185 — 10y
Yes. I have actually found a temporary solution of adding/subtracting (depending on which handle) 5 pixels. Works flawlessly. I just don't know where the 5 pixel amount comes from. The image is centered and takes up the entire canvas. MrNicNac 855 — 10y
I lied :( It only worked when the GUI rotation was < 90 or >-90 MrNicNac 855 — 10y
I tried the code and I got [this]( I used handle.Position =, centerOfEdge.x - handle.AbsoluteSize.x/2, 0, centerOfEdge.y - handle.AbsoluteSize.y/2); too. Maybe you're doing something with the result that is changing the way it looks for you. blocco 185 — 10y
Have you tried using your code at 90 degrees? ( I am adjusting nothing and using the exact code you gave me this time. MrNicNac 855 — 10y
I'm to the point where I'll go ahead and give you the whole RBXM plugin if you think you could fix it. This issue is beyond my frustration threshold. MrNicNac 855 — 10y
I tried it at 90 degrees blocco 185 — 10y
I quit MrNicNac 855 — 10y
frickedy frick stephan. Why cant anyone talk to you D: ConnorVIII 448 — 10y