Part Orientation - Get a part's orientation with 2 positions

Hello there, I intend to make a hitbox for WeldConstraints in a sandbox game I’m making
So, you have the ability to create WeldConstraints between parts (kinda cool) but I want to modelize them as Roblox does so I decided to use a beam and to good ol’ stuff

To illustrate more:

Here is an example of what I want to do
  1. You select 2 parts
  2. A weld constraint is created, and it is shown with this sweat beam and this hitbox that you can select

Click here to see the .gif

But of course, as usual, nothing is working properly as I would and, I have specific cases with my technique that caused some troubles to the system… (like this one:)

As you may notice, the hitbox is totally good. The orientation of the part simulating it is completely wrong…

I finally fixed this but now I have more problems going on.


So I tried to use some different ways and here is the current setup:
1st
So, both red parts are P0 and P1 in my script, and the ugly green part is the Hitbox Hb in my script.

Here is the script that does everything related to this hitbox

function onResize()
    if script.Parent:FindFirstChild("Hitbox") then
        local P0 = script.Parent:WaitForChild("P1")
        local P1 = script.Parent:WaitForChild("P2")

        local Hb = script.Parent:FindFirstChild("Hitbox")

        local pos = Vector3.new((P0.Position.X + P1.Position.X)/2, (P0.Position.Y + P1.Position.Y)/2, (P0.Position.Z + P1.Position.Z)/2) -- Calculate the position of the hitbox that corresponds to the middle of the segment P0 P1
        
        local coords = Vector3.new(P0.Position.X - P1.Position.X, P0.Position.Y - P1.Position.Y, P0.Position.Z - P1.Position.Z)
        local xSize = math.sqrt( coords.X^2 + coords.Y^2 + coords.Z^2 ) --Here I use a formula to calculate the length of the vector P0 P1

        --Here I am calculating director coefficients of the XY plan and XZ plan
        local dYX = (P0.Position.Y - P1.Position.Y) / (P0.Position.X - P1.Position.X)
        local dZX = (P0.Position.Z - P1.Position.Z) / (P0.Position.X - P1.Position.X)
        
        local zOrient = math.deg(math.atan(dYX)) --Angle obainted with the director coefficient dYX
        local yOrient = math.deg(math.atan(-dZX)) --Angle obtained with the direction coefficient dZX. As my base is reversed, I put it negative

        Hb.Size = Vector3.new(xSize + .25, .25, .25)
        Hb.Position = pos
        
        Hb.Orientation = Vector3.new(0, yOrient, zOrient) --Applying the orientation for the hitbox, it causes in some cases a weird offset (see the .gif below)
    end
end

script.Parent:WaitForChild("P1"):GetPropertyChangedSignal("Size"):Connect(onResize)
script.Parent:WaitForChild("P2"):GetPropertyChangedSignal("Size"):Connect(onResize)

script.Parent:WaitForChild("P1"):GetPropertyChangedSignal("Position"):Connect(onResize)
script.Parent:WaitForChild("P2"):GetPropertyChangedSignal("Position"):Connect(onResize)

The method is kind of simple.

  • I calculate the position the hitbox must have(that is the middle point of the segment P0 P1)

It works perfectly

  • I calculate the size of the hitbox (using the method to calculate the length of a vector with the vector P0 P1)

It works perfectly

  • I calculate the direction coefficient (y2 - y1) / (x2 - x1) for my XY plan, so as to use math.atan(direction coefficient) to retrieve an angle in radian, that I convert into degrees with math.deg() method.

  • I do the same for my XZ plan, but as you might have seen on one of my screen, my XZ base is reversed.
    1st
    So I need to do math.atan(-direction coefficient) to make it work.

It slighly work, on specific cases


I noticed that it worked when P0.Position.Y == P1.Position.Y for my XZ plan and when P0.Position.Z == P1.Position.Z for my XY plan. But if they are different there is an offset that is weirdly appearing…

Here is a .gif to understand

So it is kind of weird and I don’t really know to what it is related (I’m a noob with vectors and plans so)

Thanks for having even read this long message, and even more thanks if you tried to help me !

I should use CFrames but I actually don’t know what to use ngl…

I’m not particularly sure why you’re overcomplicating this so much… I see custom magnitude calculation, and a bunch of other weird stuff. I was able to do this in 8 lines of code:
https://gyazo.com/5fa605e45ec70f59f0662b8dffc6d0fd

local part0 = workspace.Part0
local part1 = workspace.Part1
local hitbox = workspace.Hitbox
game:GetService('RunService').Heartbeat:Connect(function()
	local distance = (part0.Position - part1.Position).Magnitude
	hitbox.CFrame = CFrame.lookAt(part0.Position, part1.Position) * CFrame.new(0, 0, -distance/2)
	hitbox.Size = Vector3.new((part0.Size.X + part1.Size.X)/2, (part0.Size.Y + part1.Size.Y)/2, distance)
end)

If you are gonna go this route make sure you add the x and y components to the derivative

* I calculate the direction coefficient (y2 - y1) / (x2 - x1) for my XY plan, so as to use `math.atan(direction coefficient)` to retrieve an angle in radian, that I convert into degrees with `math.deg()` method.

You need to add the offset if you are gonna use the derivative approach. However I found a much more easier method where you do a little bit what @Soliform does a while ago but this one makes it so u can move from the origin

Told you I was a n00b with CFrames, thanks a lot !