Point is in a certain 3D area of direction defined by theta

Let’s say, defining a point, we want to see, in the lookVector direction, a point is within a certain direction of that point defined by theta.

The “height” vector, (defined by dark green) in relative rotation to the point, does not matter.

image
How would I determine if the turquoise point would be in the region defined by the angle, and the green point not?

Doesn’t seem to work.

local delta = 0.15 -- the delta angle
local vectorpos = Vector3.new(0,0,0) -- the position of the detector's origin
local vectoraim = Vector3.new(0,0,1) -- the direction of the detector, should be a unit
local targetpos = Vector3,new(0,0,2) -- the position of the target point

local cosdelta = math.cos(delta);
local targetaim = (targetpos - vectorpos).unit -- the unit direction of the target (do not modify)
if vectoraim:Dot(targetaim) >= cosdelta then
    print(target is within range)
end

Minor tweaks:

  1. targetaim is adjusted to be the vector you travel to get from the source to the target (because that’s how vectoraim is defined). That is to say, I flipped the sign.
  2. We compare the dot product against math.cos(delta) instead of delta.
1 Like

All assuming delta is in radians?

Also, sometimes the dot returns -nan(ind).

By the way, if you want to know what this is for, it’s for a practical lightning generator.

The first blue pt is below the red one. I’m aiming for the generation to be above.

In this case, the X and Z relative to the red point is unneeded. The Y is what I’m struggling with.

1 Like

Although this is a 2-month bump, I recently wrote some code to solve this and thought that it may be appreciated by future readers looking for the same kind of thing. I’ve optimized it as far as reasonably possible.

local Angle = math.pi * 0.5 -- Example: 90 degrees (whole angle)

local Check = 0.5 + math.cos(Angle) * 0.5 -- Avoid trig in function call
local Epsln = 1e-5
local function Query(Pos, Dir, QueryPos)
	local Vec = QueryPos - Pos -- Subtraction
	local Dot = Dir:Dot(Vec) -- Multiplication & addition
	if Dot < 0 then -- QueryPos is behind Pos
		return false
	end
	local Dst = Vec:Dot(Vec) -- Multiplication & addition
	if Dst < Epsln then -- QueryPos coincides with Pos
		return true
	end
	return Dot * Dot / Dst >= Check -- One division, no sqrt
end
3 Likes