How do you clamp in a non-rectangular fashion?

  1. What do you want to achieve?
    I’m currently using:
local function ClosestPointOnPart(Part, Point)
		local Transform = Part.CFrame:pointToObjectSpace(Point) -- Transform into local space
		local HalfSize = Part.Size * 0.5
		return Part.CFrame * Vector3.new( -- Clamp & transform into world space
			math.clamp(Transform.x, -HalfSize.x, HalfSize.x),
			math.clamp(Transform.y, -HalfSize.y, HalfSize.y),
			math.clamp(Transform.z, -HalfSize.z, HalfSize.z)
			) * Vector3.new(1,0,1) + (Vector3.new(0,1,0) * Part.Position)
	end

To calculate the closest point on one part in relation to another part’s position. Please ignore the extra vector3s after the math.Clamp() (I want it to return a position at a constant height).
2. What is the issue?
Now, some parts that I use this formula are not rectangular. I’ve got a few sideways cylinders and wedges (essentially circles and triangles because I lock the Y Axis). Now, this formula assumes that they are rectangular, which leads to this:


As you can see, the closest point (as I placed them far away) is at the corner. Unfortunately, the parts are not actually touching.
3. What solutions have you tried so far?
I have attempted Raycasting, but to no avail. I have also browsed the forum for solutions.

In conclusion, my current formula does not clamp in the way that I want it to (either in a circular fashion or a triangular fashion as well as a rectangular fashion. I will know which.) How can I clamp like this?

If this does not work, I am happy to use different solutions like Raycasting. If so, please explain to me how those solutions work.

The Developer Forum has become invaluable as I progress with my development. Thank you all for your time and ideas!

1 Like

To get the cylinders to touch as shown in the image, you need to move them together by the distance from the edge of the cylinder to the corner of the bounding box. Here’s an example of the calculation needed to do this:

For the purposes of this example, I’ll assume the diameter of the cylinder is 12 studs.

local EdgeOffset = 12 / 2 * (math.sqrt(2) - 1)

I recently used this formula on Hotel Robloxia’s loading screen in order to have the circle transition cover the entire screen.

Edit: Presuming you know JavaScript, I found this project that may be useful. It calculates the 2d coordinates of a point on a circle’s perimeter.

So, I’m using an AlignPosition to bring the two points together. Clamping with EdgeOffset will fix my problem, however in some cases (as its part of a placement system) the point will be within the actual part. Will this be a problem if I try to use an align position with a point inside of a part?

Thank you for your examples. Do you have any idea for triangles?

Another EDIT: Perfect. Thanks for the example! Circles now work, but I still need help on triangles.