Hello!
Recently i was having some issues with detecting if two line intersect eachother. What i’ve done so far is to give the two lines a formula: ax+b, and defined all the variables exept for x.
So far i’m able to consistantly determine where it crosses, but: the lines are practically infinite, i’ve tried to comapre the Xsize of the UIframe with the magnitude of the subtraction from the absoluteposition where it intersects and the absoluteposition of the UIFrame. but that didn’t yield any satisfactory results ((PosA-PosB).magnitude).
So what other ways do i have in order to check if two lines intersect within their lenght?
I’ve aslo check wikipedia, but that gave me more of a headache than that it helped.
I’m not sure if I inderstood your problem correctly. If you are trying to find out if the intersection is inside the frame, can’t you just check if the intersection point’s x coordinate and y coordinate are both inside it?
local function isPointInFrame(p, frame)
local absPos, halfAbsSize = frame.AbsolutePosition, frame.AbsoluteSize/2
local xPos, yPos = absPos.X, absPos.Y
local hXSize, hYSize = halfSize.X, halfSize.Y
local px, py = point.X, point.Y
return px >= xPos-hXSize and px <= xPos+hXSize and py >= yPos-hYSize and py <= yPos+hYSize
end
No. that won’t help. In this example, there are 3 linepeices, 2 of wich intersect eachother. what i need to check is if two line intersect eachother within their lenghts.
Because what happens now, is that it would expect all 3 lines to cross eachother, though at different points, despite the green line already having ended well before they could even come close.
here’s the code. RC is a in y=ax+b.
It didn’t work.
function FindIntersections (RC,B)
for i,LineFolder in pairs(Lines:GetChildren()) do
for o,LinePeice in pairs(LineFolder:GetChildren()) do
if LinePeice ~= CurrentLine then
local LineRC = LinePeice.RCValue.Value
if LineRC ~= RC then
local LineB = LinePeice.BValue.Value
local LinePos = LinePeice.AbsolutePosition
local XIntersect = (RC-LineRC)/(LineB-B)
local IntersectPos = Vector2.new(XIntersect,RC*XIntersect+B)
print(IntersectPos,"//",(IntersectPos-LinePos).Magnitude)
if (IntersectPos-LinePos).Magnitude < LinePeice.AbsoluteSize.X*.5 then
print("Intersected at: ",IntersectPos)
return true
end
end
end
end
end
return false
end
I edited it to do the check for both lines. Does it now work?
function FindIntersections (RC,B)
for i,LineFolder in pairs(Lines:GetChildren()) do
for o,LinePeice in pairs(LineFolder:GetChildren()) do
if LinePeice ~= CurrentLine then
local LineRC = LinePeice.RCValue.Value
if LineRC ~= RC then
local LineB = LinePeice.BValue.Value
local LinePos = LinePeice.AbsolutePosition
local XIntersect = (RC-LineRC)/(LineB-B)
local IntersectPos = Vector2.new(XIntersect,RC*XIntersect+B)
print(IntersectPos,"//",(IntersectPos-LinePos).Magnitude)
local mag1 = (IntersectPos-LinePos).Magnitude
local mag2 = (InterSectPos-CurrentLine.AbsolutePosition).Magnitude
if mag1 < LinePeice.AbsoluteSize.X*.5 and and mag2 < CurrentLine.AbsoluteSize.X*.5 then
print("Intersected at: ",IntersectPos)
return true
end
end
end
end
end
return false
end
Sadly, this doesn’t work. I know for sure that a and b in y=ax+b are defined correctly, because whenever the rotation of the line = 0 or 180, a = 0, and b = it’s absoluteposition.Y.
so that con’t be the issue either. i cannot use raycasting either because it’s 2d.
Distance checking doesn’t seem like the most effective solution as you’d have to account for the rotation of the line too, but a better method is using some vector maths:
Say you have your four points for two lines in the screen space. You can get the lines as vectors by subtracting the lines’ points
We know that:
b = a + r;
d = c + s;
If we consider two different, randoms scalars, t and u and multiply them to our r and s line, eventually, we might reach an equality:
a + tr = c + us
The lines are intersecting if both conditions are met:
0 <= t <= 1;
0 <= u <= 1;
t and u can be calculated by getting rid of one of them in the equality. Crossing a vector by itself will return a vector with magnitude 0 and u is the scalar coefficient of vector s. Crossing s by itself will get rid of us on the right side and we’re left with:
(a + tr) x s = (c + us) x s
a x s + t(r x s) = c x s
Solving for t:
t(r x s) = (c - a) x s
t = ((c - a) x s) / (r x s)
Solving for u (Alternatively, you can plug in t into any of the equations above to solve for t):
a + tr = c + us
(a + tr) x r = (c + us) x r
a x r = c x r + u(s x r)
(a - c) x r = u(s x r)
u = (a - c) x r / (s x r)
You have both unknowns now. Now, to check if they’re intersecting:
if (t >= 0 and t <= 1) or (u >= 0 and u <= 1) then
-- intersecting
end
For the code part now:
local function intersecting(a, b, c, d)
local u = ((a - c):Cross(r)) / s:Cross(r)
local r = ((c - a):Cross(s)) / r:Cross(s)
if (t >= 0 and t <= 1) or (u >= 0 and u <= 1) then
return true
end
return false
end
After having done some editing to the function so it can be integrated into my script, i ended up with a few questions and errors. First: r was defined as a vector, but u wasn’t.
t wasn’t defined, but it was a scalar, so i hoped to be able to replace t with r, but i don’t know if that would work.
Vector3:Cross() returns a vector3 that in this case NANed out. so i used a vector2 instead. can’t wait until roblox makes vector2values a thing.
local function FindIntersections(a, b)
for i,Folder in pairs(Lines:GetChildren()) do
for o,LinePeice in pairs(Folder:GetChildren()) do
if LinePeice ~= CurrentLine then
local c = Vector3.new(LinePeice.StartPos.Value.X,LinePeice.StartPos.Value.Y)
local d = Vector3.new(LinePeice.EndPos.Value.X,LinePeice.EndPos.Value.Y)
local r = b-a
local s = d-c
local u = ((a - c):Cross(r)) / s:Cross(r)
local t = ((c - a):Cross(s)) / r:Cross(s)
if (t >= 0 and t <= 1) or (u >= 0 and u <= 1) then
return true
end
end
end
end
return false
end
Anyways, here’s the entire place. i haven’t focussed on optimizing yet.mathstoobigformybrain.rbxl (29.6 KB)
I didn’t really read through the script when I was writing, leading to errors. So, here’s the fixed intersection function:
local function intersecting(a, b, c, d)
local r, s = b - a, d - c
local u = ((a - c):Cross(r)) / s:Cross(r)
local t = ((c - a):Cross(s)) / r:Cross(s)
if (t >= 0 and t <= 1) and (u >= 0 and u <= 1) then
return true
end
return false
end
Thanks for the help. it seems like i have to edit my script quite a bit in order to get it working the way i needed it to, but it detects intersecting lines, and that’s a good place to start from!
Also thanks for teaching me this stuff. i would’ve never known what the cross product could possibly be before our maths class will eventually feature it without it.