Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Transforming 2D point to 2D object-space

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)
	end
	return Vector2.new((math.sin(rotation)), (math.cos(rotation)))
end

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 = UDim2.new(0,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?

1 answer

✓ Accepted answer

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)
	return Vector2.new(
		guiObject.AbsolutePosition.x + guiObject.AbsoluteSize.x/2,
		guiObject.AbsolutePosition.y + guiObject.AbsoluteSize.y/2
	)
end

##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 = Vector2.new(size.x, size.x) -- moves like a circle
		rotation = rotation - math.pi;
	elseif edge == "Top" then
		size = Vector2.new(size.y, size.y)
		rotation = rotation - math.pi/2;
	elseif edge == "Right" then
		size = Vector2.new(size.x, size.x)
		rotation = rotation;
	elseif edge == "Bottom" then
		size = Vector2.new(size.y, size.y)
		rotation = rotation + math.pi/2;
	end
	rotation = -rotation; -- clockwise
	return center + (size/2) * Vector2.new(
		math.cos(rotation),
		-math.sin(rotation) -- to fix flipped y-axis
	)
end

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

17 comments

1

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."

0

My bad. The X coordinate seems rather fine (mine was as well); but, again like mine, the Y coordinate is very off.

0

How are you using my code? I'm getting the center of the edge each time I call the function.

0

UDim2.new(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?

0

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.

0

I have fixed it, and edited my answer accordingly.

0

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?

0

Here (http://i.imgur.com/lnH7IgW.png) is an image of what is happening (only pay attention to the left-side handle at the moment)

0

Is your image centered?

0

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.

0

I lied :( It only worked when the GUI rotation was < 90 or >-90

0

I tried the code and I got this. I used handle.Position = UDim2.new(0, 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.

0

Have you tried using your code at 90 degrees? (http://i.imgur.com/EY1EzLl.png?1) I am adjusting nothing and using the exact code you gave me this time.

0

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.

0

I tried it at 90 degrees http://imgur.com/M0I7Toy

0

I quit

0

frickedy frick stephan. Why cant anyone talk to you D:

This discussion is preserved as it was. New answers, comments, and votes are closed.