Currently I’m working on floor placement which is done via triangulation, but want to make an exception when one of the triangles that is returned from the triangulation result is a right angle because textures look nicer on a single wedge than on a two-part wedge.
I’ve implemented it but I’m thinking that making a whole CFrame just for the triangle’s dimensions is excessive. So I am just wondering if there are any alternative means of getting the dimensions of a right triangle without creating a whole CFrame and using object/world space, and without using magnitude because it’s slow? Note the triangle might not be axis parallel so subtracting vectors from one another may not work.
HALF_PI is pi / 2, and FLOATING_POINT_EPSILON is 0.01. Here are the relevant functions so there isn’t any missing information in the process but the main part is near the end in the drawTriangle function:
local function distanceFromIncrement(number: number, increment: number) -- gets how far a number is from a specified increment
return math.abs(number - (math.round(number / increment) * increment))
end
local function getAngle(a: Vector3, b: Vector3, c: Vector3) -- gets angle between a, b, and c's unit vectors
return math.acos(((a - b).Unit):Dot((c - b).Unit))
end
local function isRight(a: Vector3, b: Vector3, c: Vector3) -- calculates whether or not the 3 vertices make up a right triangle. If it does, also returns 3 vertices (abc) where B is the right angle
local angle = getAngle(a, b, c)
local rightABC = distanceFromIncrement(getAngle(a, b, c), HALF_PI) <= FLOATING_POINT_EPSILON
if rightABC then
return true, a, b, c
end
local rightBCA = distanceFromIncrement(getAngle(b, c, a), HALF_PI) <= FLOATING_POINT_EPSILON
if rightABC then
return true, b, c, a
end
local rightCAB = distanceFromIncrement(getAngle(c, a, b), HALF_PI) <= FLOATING_POINT_EPSILON
if rightCAB then
return true, c, a, b
end
end
local function drawTriangle(a: Vector3, b: Vector3, c: Vector3, parent: Instance?)
local isTriRight, newA, newB, newC = isRight(a, b, c) -- B is always the right angle, A and C are the other 2 vertices
if isTriRight then
local ab, cb = (newA - newB).Unit, (newC - newB).Unit -- directions from B to A and B to C
local up = ab:Cross(cb) -- up vector for BAMatrix
-- next few lines is where things go south.
-- I think using a whole CFrame just to obtain distance between 2 points may be overcomplicated
-- but magnitude is slow so I'm not sure what's more performant in this case or if there are any other options
local baMatrix = CFrame.lookAt(newB, newA, up)
local aRelative, cRelative = baMatrix:PointToObjectSpace(newA), baMatrix:PointToObjectSpace(newC)
-- now draw the triangle between the three vertices
local newWedge = makePart('Wedge')
newWedge.Size = Vector3.new(0, math.abs(aRelative.Z), math.abs(cRelative.X))
newWedge.CFrame = CFrame.fromMatrix(
(newA + newC) / 2,
-up,
ab,
-cb
)
-- debug
newWedge.Color = Color3.new(1,0,1)
newWedge.Parent = parent
return newWedge
end
Thanks in advance for any help!