Line intersection on walls

I have a wall generator, that generates walls between 2 points, like so



I want to be able to know if said walls are intersecting one another, and if so, be able to place a point at the intersection, and update the walls to have new end points. So the idea would be, instead of 2 walls here, it’d be split into 4 walls (color coded) and have their start and end points changed to match the intersecting pole

When a wall is generated, this is how I store the pole and wall positions

local function StorePole(pole)
	if not AllPoles[pole] then
		AllPoles[pole] = {}
	end
end

local function StoreWall(wall, startPoint, endPoint)
	if not AllWalls[wall] then
		AllWalls[wall] = {}
	end
	
	table.insert(AllPoles[startPoint], wall)
	table.insert(AllPoles[endPoint], wall)
	
	AllWalls[wall] = {
		Start = startPoint,
		End = endPoint
	}
end

-- Generate wall
StorePole(Pole1.Position)
StorePole(Pole2.Position)

StoreWall(WallModel, Pole1.Position, Pole2.Position)

So you basically store the poles position, and the pole has any walls that are attached to it added to their table, and the walls have the start and end pole added.

And then I tried this function, which I found here

function intersection_point(line_1_start, line_1_end, line_2_start, line_2_end)
	print(line_1_start, line_1_end, line_2_start, line_2_end)
	local line_1_m = (line_1_end.Z - line_1_start.Z) / (line_1_end.X - line_1_start.X)
	local line_2_m = (line_2_end.Z - line_2_start.Z) / (line_2_end.X - line_2_start.X)
	local line_1_b = line_1_start.Z - (line_1_m * line_1_start.X)
	local line_2_b = line_2_start.Z - (line_2_m * line_2_start.X)
	local intersect_x = (line_2_b - line_1_b) / (line_1_m - line_2_m)
	local intersect_z = (line_1_m * intersect_x) + line_1_b
	return Vector3.new(intersect_x, line_1_start.Y, intersect_z)
end

for wall, polePositions in pairs(AllWalls) do
		local Intersect = intersection_point(
			Pole1.Position, -- Pole1 and Pole2 are the most recent poles of the wall being added
			Pole2.Position,
			polePositions.Start,
			polePositions.End
		)
		
		if Intersect then
			print(Intersect)
		end
	end

However, Intersect returns nan, 6, nan

May I ask what the output of this: print(line_1_start, line_1_end, line_2_start, line_2_end) is?

-1 -1 -41 -41

So it’s basically doing 0 / 0 in the end :confused: unsure what I’m doing wrong

Thats odd.
They are meant to be vectors, so why are they just single numbers per?
Is the -1 -1 -41 -41 exactly what was outputted, over the multiple lines?

Oh wait sorry, I printed the wrong ones.
-47, 6, 6 -12, 6, -29 -47, 6, 6 -12, 6, -29

by the looks of things, local intersect_x = (line_2_b - line_1_b) / (line_1_m - line_2_m)
always results in 0/0, which causes the math error. intersect_z then relies on intersect_x, which is why it also errors. ill quickly try and find the issue

Spent a few minutes working out the math, then realised the error is caused by both of the lines being identical (same start and same end points)

Can you please replace

for wall, polePositions in pairs(AllWalls) do
		local Intersect = intersection_point(
			Pole1.Position, -- Pole1 and Pole2 are the most recent poles of the wall being added
			Pole2.Position,
			polePositions.Start,
			polePositions.End
		)
		
		if Intersect then
			print(Intersect)
		end
	end

with

for wall, polePositions in pairs(AllWalls) do
        if not (Pole1.Position == polePosition.Start) and not (Pole2.Position == polePosition.End) then
		    local Intersect = intersection_point(
			    Pole1.Position, -- Pole1 and Pole2 are the most recent poles of the wall being added
			    Pole2.Position,
			    polePositions.Start,
			    polePositions.End
		    )
		
		    if Intersect then
			    print(Intersect)
		    end
	end
end

I added a small check to ensure that the lines are not the same.
Idk if this will prevent it from running at all, but its worth a try

That worked! :smiley:

However, I’m not sure if there’s issues with the function, or just how I am storing walls and poles, but if there’s a pole position that connects 2 walls, I get a nan result for one of the intersecting results :confused:

It seems like it’s adding them in correctly though, but I don’t know
image

As there 6 poles, 2 share the same coord, so only 5 get added into the table. Pole[1] has 2 wall objects which is correct. So everything seems to check out correctly.

It may work if i switch the AND to an OR in the script I sent earlier:

for wall, polePositions in pairs(AllWalls) do
        if not (Pole1.Position == polePosition.Start) or not (Pole2.Position == polePosition.End) then
		    local Intersect = intersection_point(
			    Pole1.Position, -- Pole1 and Pole2 are the most recent poles of the wall being added
			    Pole2.Position,
			    polePositions.Start,
			    polePositions.End
		    )
		
		    if Intersect then
			    print(Intersect)
		    end
	end
end

image
Ended up printing the nan twice :confused:

With some prints
image

for wall, polePositions in pairs(AllWalls) do
		if not (Pole1.Position == polePositions.Start) or not (Pole2.Position == polePositions.End) then
			local Intersect = GetLineIntersection(
				Pole1.Position, -- Pole1 and Pole2 are the most recent poles of the wall being added
				Pole2.Position,
				polePositions.Start,
				polePositions.End
			)
			
			if Intersect then
				print(
					"Intersecting @", Intersect, "\n",
					"Pole1 Position @", Pole1.Position, "\n",
					"Pole2 Position @", Pole2.Position, "\n",
					"Start Position @", polePositions.Start, "\n",
					"End Position @", polePositions.End
				)
				local IntersectPole = script.IntersectPole:Clone()
				IntersectPole.Position = Intersect
				IntersectPole.Parent = workspace
			end
		end
	end

Color coded for extra help
image
It the second print should be ignored (first nan) as poles in the same position should be ignored. It’s only when there’s an intersection of walls where no pole exists that’d I want detected, so I can create poles in those intersecting parts, and then split walls as needed

EDIT
More testing, I noticed that there was stuff returning nil

function GetLineIntersection(line_1_start, line_1_end, line_2_start, line_2_end)
	local line_1_m = (line_1_end.Z - line_1_start.Z) / (line_1_end.X - line_1_start.X)
	print(line_1_end.Z - line_1_start.Z, line_1_end.X - line_1_start.X)
	local line_2_m = (line_2_end.Z - line_2_start.Z) / (line_2_end.X - line_2_start.X)
	local line_1_b = line_1_start.Z - (line_1_m * line_1_start.X)
	local line_2_b = line_2_start.Z - (line_2_m * line_2_start.X)
	print(line_1_m, line_2_m, line_1_b, line_2_b)
	local intersect_x = (line_2_b - line_1_b) / (line_1_m - line_2_m)
	local intersect_z = (line_1_m * intersect_x) + line_1_b
	print(intersect_x, intersect_z)
	return Vector3.new(intersect_x, line_1_start.Y, intersect_z)
end

15:52:45.336 -35 0 - Server - Script:10
15:52:45.336 -inf 0 -inf -19 - Server - Script:14
15:52:45.336 nan nan - Server - Script:17

Unsure why it getting -inf

what are the coordinates of line_1_start, line_1_end, line_2_start, and line_2_end?
Its likely a math error

Did more testing. It’s due to them having the same X


So it seems to be an issue where connecting in straight lines. Diagonals work fine, so I don’t know.

Since

line_1_end.X - line_1_start.X

is basically -12 - (-12) thus 0, and then -35/0 is -inf

Thought that might be the case. Its the gradient of it.

Gradient of a vertical line: inf (or -inf, whatever)
Gradient of a horizontal line: undefined (NAN)

What do I do to resolve that???