3: Hello everyone!
I’ve seen a lot of people suffer from this systen from its difficulty.
so why not just making tutorial about how you can make one
Tutorials List:
- Before we start
2.We arrange the numbers from the smallest to the oldest in terms of the first Edge that was
3. We merge every Edge or the other by using ray / beam part
4.We arrange the numbers from the smallest to the oldest in terms of the first Edge that was placed
5.If the angle is good we will make a triangle between before and after it because the triangle needs 3 Edges to complete
Start with sketch!
first you when player finished with his position of the area
the Edge will be kinda random like this
but the Edge will be named so that will know where the first Edge and where is the last Edge
After you connect between the first Edge and the second Edge you will have a vision of what the player look like that he wants
And you will start from the corner to the last angle, but in each corner you will try tests on each corner to make sure that this angle is really the same as what we want (the triangle is not an exit from the area that we have determined, we make sure that we do not cover another triangle or cover another Edge)
and make sure the angle from 1,9,2
is under 180 Angle
-- This is a script only to connect Edges between the second and the Edge
local IndexList = {1,4,6,2,5,7,8,9,3}
table.sort(IndexList , function(a,b) return tonumber(a.Name) < tonumber(b.Name) end) -- To make the salary from the smallest number to the biggest number and this is very important in this process
function createPivotingLinesOffset(PosA: Vector3, PosB: Vector3): ()
local beam = Instance.new("Part", workspace.Lines)
beam.Color=Color3.fromRGB(128, 187, 219)
beam.FormFactor = "Custom"
beam.Material = "Neon"
beam.Transparency = 0.8
beam.Anchored = true
beam.Locked = true
beam.CanCollide = false
beam.Position = PosA
local StartingCF = CFrame.new(beam.Position,PosB)
local cf = StartingCF:ToWorldSpace(CFrame.new(0,0,-(PosB-PosA).Magnitude/2))
beam.CFrame=cf
beam.Size=Vector3.new(.3,.3,(PosB-PosA).Magnitude)
return beam
end;
for i, v in pairs(IndexList) do
local a = GetItem(i)
local b = GetItem(i-1)
--local c = GetItem(i+1)
createPivotingLinesOffset(a,b)
end
local v1 = a.Position - b.Position
local v2 = c.Position - a.Position
local crossproduct = v2:Cross(v1)
local currentDirection
if crossproduct.Y > 0 then
currentDirection = 1
else
currentDirection = -1
end
return currentDirection ~= 1
After making sure that 1
does not contain an inside Edge or cover a triangle and that 1
is valid to be triangle
We will put the data of 1 in a triangle table and we gonna remove 1
from indexlist
and making tangle by 1,2,9
Because 9
is before 1 and 2
is after 1
-- this script for making trangle
function drawTriangle(a: Vector3, b: Vector3, c: Vector3, parent: any): ()
local edges = {
{longest = (c - b), other = (a - b), position = b};
{longest = (a - c), other = (b - c), position = c};
{longest = (b - a), other = (c - a), position = a};
};
table.sort(edges, function(a, b) return a.longest.magnitude > b.longest.magnitude end);
local edge = edges[1];
local theta = math.acos(edge.longest.unit:Dot(edge.other.unit))
local s1 = Vector2.new(edge.other.magnitude * math.cos(theta), edge.other.magnitude * math.sin(theta));
local s2 = Vector2.new(edge.longest.magnitude - s1.x, s1.y);
local p1 = edge.position + edge.other * 0.5
local p2 = edge.position + edge.longest + (edge.other - edge.longest) * 0.5
local right = edge.longest:Cross(edge.other).unit;
local up = right:Cross(edge.longest).unit;
local back = edge.longest.unit;
local cf1 = CFrame.new(
p1.x, p1.y, p1.z,
-right.x, up.x, back.x,
-right.y, up.y, back.y,
-right.z, up.z, back.z
);
local cf2 = CFrame.new(
p2.x, p2.y, p2.z,
right.x, up.x, -back.x,
right.y, up.y, -back.y,
right.z, up.z, -back.z
);
local w1 = self._wdagePart:Clone();
local w2 = self._wdagePart:Clone();
w1.Parent = parent;
w2.Parent = parent;
w1.Color=self._Color or Color3.fromRGB(128, 187, 219)
w2.Color=self._Color or Color3.fromRGB(128, 187, 219)
w1.Transparency=.9
w2.Transparency=.9
w1.Material=Enum.Material.Neon
w2.Material=Enum.Material.Neon
w1.Size = Vector3.new(0, s1.y, s1.x);
w2.Size = Vector3.new(0, s2.y, s2.x);
w1.CFrame = cf1;
w2.CFrame = cf2;
w1.CanCollide = false
w2.CanCollide = false
end;
A script that makes sure that there is no Edge about the Edge that we are test on it
local contained = false
for x,v in pairs(IndexList) do
if v ~= A and v ~= B and v ~= C then
local a1,a2,a3 = self.GetAreaOfTriangle(A, B, v), self.GetAreaOfTriangle(A, C, v), self.GetAreaOfTriangle(B, C, v)
if a1 + a2 + a3 == self.GetAreaOfTriangle(A, B, C) then
contained = true
end
end
end
if not contained then
--found ear!
end
After tests with Edge 2 it turns out that it is not qualified to be a triangle now and we will skip it for now
and by make them loop it’s done!!
resources
http://www.personal.kent.edu/~rmuhamma/Compgeometry/MyCG/TwoEar/two-ear.htm
http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/algorithm2.htm
and it’s works!
i hope i helped you <3 thank you for @Zairky for helping me with his tutorial ;3
sorry for my broken grammar if you don’t understand anything of these try use this script that i made!
Polygon Triangles.rbxm|attachment Free Model (5.9 کیلوبایت)
Note: this system took me 15 days of working. Because it’s hard to understand.