I have 3 points But I want to have a triangle part that is created from these 3 Points so i could make “Shards” from it The triangle is not in 2d space but can be represented in 2d space.
What are you using to create the triangle? EditableMeshes?
I want to use the triangle as a shard so i would need to cut it from a part
So, by using the CSG API? Specifically :SubtractAsync()
?
You want to make triangle out of 2 wedges? If yes, I can give you code to do so.
yes but how would i get the Shape out of it because when i tried to sub the lines creating that pieceit obviously as expected Only cut the outer lines
Yeah sure thats what i originally thought to do im just not that good with trigo to be able to do it
local wedge = Instance.new("WedgePart");
wedge.Anchored = true;
wedge.TopSurface = Enum.SurfaceType.Smooth;
wedge.BottomSurface = Enum.SurfaceType.Smooth;
local function draw3dTriangle(a, b, c)
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));
local w1 = 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 = workspace;
local w2 = wedge:Clone();
w2.Size = Vector3.new(0, height, math.abs(ac:Dot(back)));
w2.CFrame = CFrame.fromMatrix((a + c)/2, -right, up, -back);
w2.Parent = workspace;
return w1, w2;
end
Use that function.
Run it by just passing your three vector 3 points.
Could you explain how this works? Maybe if you know
It’s just maths. I don’t know what I can explain about maths.
This is from EgoMoose, he wrote an article on it here: Articles/3d triangles/3D triangles.md at master · EgoMoose/Articles · GitHub
Here it is:
local function CalculateTriangle(a,b,c)
local ax,ay,az=a.x,a.y,a.z
local bx,by,bz=b.x,b.y,b.z
local cx,cy,cz=c.x,c.y,c.z
local px,py,pz=ax,ay,az
local tx,ty,tz=cx,cy,cz
local v0x,v0y,v0z=bx-ax,by-ay,bz-az
local v1x,v1y,v1z=cx-ax,cy-ay,cz-az
local d01=v0x*v1x+v0y*v1y+v0z*v1z--In case of case 2 triangle. Speeds it up a lot
local d=d01/(v0x*v0x+v0y*v0y+v0z*v0z)
if d>0 then
if d>1 then--Case 2 triangle
tx,ty,tz=bx,by,bz
v0x,v0y,v0z,v1x,v1y,v1z=v1x,v1y,v1z,v0x,v0y,v0z
d=d01/(v0x*v0x+v0y*v0y+v0z*v0z)
-- else Case 1 triangle
end
else--Case 3 triangle. Don't get a case 3 triangle lol. Slowest of them all.
px,py,pz=cx,cy,cz
tx,ty,tz=ax,ay,az
v0x,v0y,v0z=bx-cx,by-cy,bz-cz
v1x,v1y,v1z=-v1x,-v1y,-v1z
d=(v0x*v1x+v0y*v1y+v0z*v1z)/(v0x*v0x+v0y*v0y+v0z*v0z)
end
local y0x,y0y,y0z=tx-px-d*v0x,ty-py-d*v0y,tz-pz-d*v0z
local l0,l1=(v0x*v0x+v0y*v0y+v0z*v0z)^0.5, (y0x*y0x+y0y*y0y+y0z*y0z)^0.5
local hy0x,hy0y,hy0z,hd=y0x*0.5,y0y*0.5,y0z*0.5,d*0.5
local tf=0.5+hd
local oyx,oyy,oyz,ozx,ozy,ozz=y0x/l1,y0y/l1,y0z/l1,v0x/l0,v0y/l0,v0z/l0
local oxx,oxy,oxz=oyy*ozz-oyz*ozy,oyz*ozx-oyx*ozz,oyx*ozy-oyy*ozx
local Tris1CF = CFrame.new(v0x*hd+hy0x+px,v0y*hd+hy0y+py,v0z*hd+hy0z+pz, oxx,oyx,ozx,oxy,oyy,ozy,oxz,oyz,ozz)
local Tris2CF = CFrame.new(v0x*tf+hy0x+px,v0y*tf+hy0y+py,v0z*tf+hy0z+pz,-oxx,oyx,-ozx,-oxy,oyy,-ozy,-oxz,oyz,-ozz)
local Size1 = Vector3.new(0.001,l1,d*l0)
local Size2 = Vector3.new(0.001,l1,(1-d)*l0)
return Tris1CF, Size1, Tris2CF, Size2
end
I’m not owner of this code though, and this complex math as I know is the most optimized, cuz only basic math operations used.
First, let us visualize 3 points a, b, c
in space. It should look something like this:
Now, lets focus on the first line of the function.
local ab, ac, bc = b - a, c - a, c - b
Lets say you take two points in space, a, b
. Now, if you do (b - a)
, it simply returns a vector that starts off at point a
, and ends at point b
. We call this vector AB. Here is an image.
The first line of code just gets the vectors AB, AC, BC
.
Next, lets take a look at the second line.
local abd, acd, bcd = ab:Dot(ab), ac:Dot(ac), bc:Dot(bc)
Assume you have a vector called AB
. When you dot AB
with itself, you get the magnitude squared, also known as the length of the vector but SQUARED. What the code does is simply get the squared lengths of the vectors AB, AC, and BC
. Learn more about dot products here.
Moving onto the next few lines of code.
if (abd > acd and abd > bcd) then
c, a = a, c
elseif (acd > bcd and acd > abd) then
a, b = b, a
end
What this does is simply swap the a
and c
coordinates if the squared length of AB
is greater than AC
and BC
. If the first if statement doesn’t hold true, it swaps the a
and b
coordinates if the squared length of AC
is greater than BC
and AB
.
ab, ac, bc = b - a, c - a, c - b
This line simply recalculates the vectors (look above for explanation), since the coordinates might have been swapped.
Let us now look at the next few lines of code.
local right = ac:Cross(ab).Unit
local up = bc:Cross(right).Unit
local back = bc.Unit
The first line returns a unit vector facing the right (the black arrow) like this:
The second line returns a unit vector that faces up like this:
Finally, the third line simply returns the normalized version (has a length of 1) of the vector BC
like this:
Learn more about cross products here.
Moving onto the next line.
local height = math.abs(ab:Dot(up))
This line returns the height of the triangle, and the math.abs
is to ensure the height is always positive. Look at the image below for a visual (the black line).
Now, the next line.
w1.Size = Vector3.new(0, height, math.abs(ab:Dot(back)))
When you dot AB
with back
, you get the length of the base of the triangle.
Next line.
w1.CFrame = CFrame.fromMatrix((a + b) / 2, right, up, back)
This line simply constructs a new CFrame. The first parameter is the mid point of our two vectors a
and b
, the second parameter is our right vector, the third parameter is our up vector, and the last parameter is the back vector. Look above if you want visuals for right, up, and back vectors.
Lets look at our next line of code.
w2.Size = Vector3.new(0, height, math.abs(ac:Dot(back)))
This also returns the length of the triangle base.
Our final line of code.
w2.CFrame = CFrame.fromMatrix((a + c) / 2, -right, up, -back)
This line also constructs a new CFrame, but our parameters are a bit different this time. The first parameter is the mid point of our two vectors a
and c
, the second parameter is our left vector (if you add a negative to a vector, it flips the direction), the third parameter is our up vector, and the last parameter is the forward vector.
Hopefully this helped you understand the code. If you have any further questions, feel free to ask me.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.