Checking if a vector3 is between 2 other vector3

Currently I am working on a magic system for my game. Currently projectiles to be specific. I’m trying to figure out a good way to prevent a possible exploit.

I can fire a remote to cause the projectile to explode where I want. the solution I have for it is simple to write down but I can’t think of the math needed. basically I need the math to be able to calculate if the explosion point is between the start and end point

here is a function I tried to make but it doesn’t work that well and sometimes returns false when its supposed to be true. I have tried looking up solutions but I get answers for problems different than my own.

function IsPointBetween(Point1, Point2, PointBetween)
	local Discrep = 5
	local function CheckPoint(Point1Axis, Point2Axis, PointBetweenAxis)
		if Point1Axis < 0 then
			Point1Axis = Point1Axis + (-1*Discrep)
		else
			Point1Axis = Point1Axis + (Discrep)
		end
		if Point2Axis < 0 then
			Point2Axis = Point2Axis + (-1*Discrep)
		else
			Point2Axis = Point2Axis + (Discrep)
		end
		local BetweenPoint = false
		if Point1Axis > Point2Axis then
			if PointBetweenAxis <= Point1Axis and PointBetweenAxis >= Point2Axis  then
				BetweenPoint = true
			end
		elseif Point1Axis < Point2Axis then
			if PointBetweenAxis >= Point1Axis and PointBetweenAxis <= Point2Axis  then
				BetweenPoint = true
			end
		end
		return BetweenPoint
	end
	local X = CheckPoint(Point1.X, Point2.X, PointBetween.X)
	local Z = CheckPoint(Point1.Z, Point2.Z, PointBetween.Z)
	if X and Z then
		return true
	else
		return false
	end
end
1 Like

Probabley create a ray between the two target points and fetch information from there?

Given the two endpoints and the middle point, you can establish if they are collinear by checking if they don’t form a triangle.

Let:

  • The start point = point A
  • The explosion point = point B
  • The end point = point C

and in calculating the length values of AB, BC, and AC…

If AB + BC = AC, then it’s a line, and the explosion point is inside of the line.

Granted, we’re dealing with floating point precision so it really should be

math.abs((AB + BC) - AC) < 0.001

but that should generally be accurate enough for your needs.

1 Like
range = (B-A).unit:Dot(C-A) / (B-A).magnitude
isBetween = range >= 0 and range <= 1

You have to reduce your component A, B, and C to put them in terms of A so that you have direction vectors and not position vectors. Then you can get the dot from B-A unit vector to C-A, which will be scaled from 0 to the length of C-A. Then just divide by the length. 0 means C=A, 1 means C=B.

Edit: Or are you trying to see if the point is along the line segment? In that case you just do a distance from line segment with a non-zero tolerance like 0.01. Here’s a good response on SO: language agnostic - Shortest distance between a point and a line segment - Stack Overflow

2 Likes

If you want to check if they are perfectly between each you could just compare the directional vectors, but there might be floating point errors. For example try do this:

local PointInBetweenDirection = (PointInBetween - StartPoint).Unit
local EndPointDirection = (EndPoint - StartPoint).Unit

print(PointInBetweenDirection, EndPointDirection)

You will see that the directional vectors are almost the same but the floating point errors will throw it off so you can’t compare them directly but you could do one decimal place.

Hi there! I think I found another of checking if the point lies between and I wanted to get your input on if its valid, it seems to work perfectly fine but are there any edge cases that could make it fail? (I can’t think of any)

local PointA --this is the start point
local PointB --this is the end point
local PointC --this is the point between

print(((PointC - PointA).Unit - (PointB - PointA).Unit).Magnitude <= 0.01)

That’s only checking if the directions are similar. It will give false positives if C before A or past B. You don’t really want to compare the units either because your tolerance will be in relative angular space instead of global 3d space - which means your tolerance will be too low when the points are close and too high when the points are far.

oh yes you are correct thank you very much, and btw would you mind explaining the StackOverflow solution, since I will be implementing moving projectiles in a project of mine, so I need to verify the raycast hit point on the server. (nvm figured it out)