Triangles with Egomooses function

Hello! Using @EgoMoose triangle function, I was wondering if anyone knew how to prevent this middle line when two triangles intersect. Thank you Egomoose for the function. Spoilers! I’m terrible with math…

local wedge = Instance.new("WedgePart");
wedge.Anchored = true;
wedge.TopSurface = Enum.SurfaceType.Smooth;
wedge.BottomSurface = Enum.SurfaceType.Smooth;

local function draw3dTriangle(a, b, c, parent, w1, w2)
	local ab, ac, bc = b - a, c - a, c - b;
	local abd, acd, bcd = ab:Dot(ab), ac:Dot(ac), bc:Dot(bc);
	
	if (abd > acd and abd > bcd) then
		c, a = a, c;
	elseif (acd > bcd and acd > abd) then
		a, b = b, a;
	end
	
	ab, ac, bc = b - a, c - a, c - b;
	
	local right = ac:Cross(ab).unit;
	local up = bc:Cross(right).unit;
	local back = bc.unit;
	
	local height = math.abs(ab:Dot(up));
	
	w1 = w1 or wedge:Clone();
	w1.Size = Vector3.new(0, height, math.abs(ab:Dot(back)));
	w1.CFrame = CFrame.fromMatrix((a + b)/2, right, up, back);
	w1.Parent = parent;
	
	w2 = w2 or edge:Clone();
	w2.Size = Vector3.new(0, height, math.abs(ac:Dot(back)));
	w2.CFrame = CFrame.fromMatrix((a + c)/2, -right, up, -back);
	w2.Parent = parent;
	
	return w1, w2;
end

The issue arises from the fact that parts can’t be planes: even though the code tells the wedges’ Size.X to be 0, ROBLOX’s internal engine updates it to the minimum value (currently 0.05) upon being set. BaseParts must always have some thickness, and that thickness is where the line is coming from.

I’ve made some slight modification to the code to account for this and even offers a customizable THICKNESS constant, but an entirely unavoidable issue with this process will be the overlapping of parts at their tips (see below, albeit with a very high thickness to emphasize the point).

image

If you can hide this, you’re all good, but if you can’t, you may need to look into making a mesh for whatever you’re trying to do. Either way, here is the modified code:

local wedge = Instance.new("WedgePart");
wedge.Anchored = true;
wedge.TopSurface = Enum.SurfaceType.Smooth;
wedge.BottomSurface = Enum.SurfaceType.Smooth;

local THICKNESS = 0.05

local function draw3dTriangle(a, b, c, parent, w1, w2)
	local ab, ac, bc = b - a, c - a, c - b;
	local abd, acd, bcd = ab:Dot(ab), ac:Dot(ac), bc:Dot(bc);

	if (abd > acd and abd > bcd) then
		c, a = a, c;
	elseif (acd > bcd and acd > abd) then
		a, b = b, a;
	end

	ab, ac, bc = b - a, c - a, c - b;

	local right = ac:Cross(ab).unit;
	local up = bc:Cross(right).unit;
	local back = bc.unit;

	local height = math.abs(ab:Dot(up));
	
	w1 = w1 or wedge:Clone();
	w1.Size = Vector3.new(THICKNESS, height, math.abs(ab:Dot(back)));
	w1.CFrame = CFrame.fromMatrix((a + b)/2, right, up, back);

	w2 = w2 or wedge:Clone();
	w2.Size = Vector3.new(THICKNESS, height, math.abs(ac:Dot(back)));
	w2.CFrame = CFrame.fromMatrix((a + c)/2, -right, up, -back);
	
	local modifier = ((w1.CFrame * CFrame.new(-1,0,0)).Position.Y < w1.Position.Y) and 1 or -1
	
	w1.CFrame *= CFrame.new(modifier * -THICKNESS/2,0,0)
	w2.CFrame *= CFrame.new(modifier * THICKNESS/2,0,0)
	
	w1.Parent = parent;
	w2.Parent = parent;

	return w1, w2;
end

One final thing to note is that this code normalizes the wedges so that their highest face is what is lined up with the provided triangle. This may lead to unexpected results when working with perfectly vertical triangles. To remove this behavior, you just need to remove modifier and its usage in the second CFrame manipulations. If you do choose to remove the normalization, bear in mind that the order you specify your points in will determine which direction the wedges “slide” in.

3 Likes

Edit: Oops, didn’t realize our suggestions where almost the same.

Give this modification a go. It will fix the connectivity on the top side of the parts. The bottom side will still have a gap or overlap sometimes. What I did was slide the wedges down by half of their thickness so that the top edge meets at the theoretical points you used to create them, rather than them joining in the middle of the wedge.

local wedge = Instance.new("WedgePart");
wedge.Anchored = true;
wedge.TopSurface = Enum.SurfaceType.Smooth;
wedge.BottomSurface = Enum.SurfaceType.Smooth;

local function draw3dTriangle(a, b, c, parent, w1, w2)
	local ab, ac, bc = b - a, c - a, c - b;
	local abd, acd, bcd = ab:Dot(ab), ac:Dot(ac), bc:Dot(bc);
	
	if (abd > acd and abd > bcd) then
		c, a = a, c;
	elseif (acd > bcd and acd > abd) then
		a, b = b, a;
	end
	
	ab, ac, bc = b - a, c - a, c - b;
	
	local right = ac:Cross(ab).unit;
	local up = bc:Cross(right).unit;
	local back = bc.unit;
	
	local height = math.abs(ab:Dot(up));
	
	w1 = w1 or wedge:Clone();
	w1.Size = Vector3.new(0, height, math.abs(ab:Dot(back)));
	w1.CFrame = CFrame.fromMatrix((a + b)/2, right, up, back);
	-- MODIFICATION
	if w1.CFrame.RightVector.Y < 0 then
		w1.CFrame = w1.CFrame * CFrame.new(w1.Size.x/2, 0, 0)
	else
		w1.CFrame = w1.CFrame * CFrame.new(-w1.Size.x/2, 0, 0)
	end
	-- /MODIFICATION
	w1.Parent = parent;
	
	w2 = w2 or wedge:Clone();
	w2.Size = Vector3.new(0, height, math.abs(ac:Dot(back)));
	w2.CFrame = CFrame.fromMatrix((a + c)/2, -right, up, -back);
	-- MODIFICATION
	if w2.CFrame.RightVector.Y < 0 then
		w2.CFrame = w2.CFrame * CFrame.new(w2.Size.x/2, 0, 0)
	else
		w2.CFrame = w2.CFrame * CFrame.new(-w2.Size.x/2, 0, 0)
	end
	-- /MODIFICATION
	w2.Parent = parent;
	
	return w1, w2;
end
2 Likes