I’m having a hard time figuring this out, not that good at vectors, from a single vector location I’m trying to figure out how to do a “Cylinder mask made with checks” being able to orient it from that central point in order to trigger a response when actor is inside the Cylinder bounds.
Looking to do this with just vector math or math expressions as creating an actor and using collisions ain’t an option in this case.
Aiming to just being able to orient the Cylinder rotating it by the Z axis
So far I believe I’m on the right path getting the vertical height using the cylinder radius by just subtracting the Actors Z with Point Z and checking if it’s inside its radius.
Not having that luck with the X/Y handling though as I’m ending up just creating a square x) by getting the distance and comparing it with the Radius too (not weight).
the orientation of your cylinder is known. it is the vector of the cylinder axis
we can write down the planes coordinate equation which is: n.xx + n.yy + n.z*z = d, The normal vector n is made up by n.x,n.y and n.z as its xyz coordinates. It must be a unit vector.
calculate d for the plane of interest where your point of interest is on.
what you want to do next is calculate the intersection point of your cylinder axis with that plane in order to measure the distance between your point of interest and the cylinder axis.
therefore set up a straight light equation (of the cylinder axis) X = P + r * n where P is the centre of the cylinder and n the normal vector of your plane.
fill in the equation above:
x = P.x + r * n.x
y = P.y + r * n.y
z = P.t + r * n.z
n.x * (P.x + r * n.x) + n.y * (P.y + r * n.y) + n.z * (P.z + r * n.z) = d
→ what we are interested in is
r = (d - (n.xP.x + n.yP.y +n.zP.z)) / (n.xn.x +n.yn.y + n.zn.z)
calculate X = P + r * n to find the closest point on the cylinder axis to our point of interest.
by measuring the distance between X and our point of interest you can determine if it is within the radius of an infinite cylinder along the given axis.
by measuring the distance between X and the center point of your cylinder you can determine if it is within the cylinder of a given length.
p.s. long post, hope i did not mess up but very confident about the approach.
This definitely worked, spended all day figuring this out indeed it works! Finally created a C++ method as in BP was having a hard time recreating all the math. A hundred thanks my friend!
If anyone is ever interested ended up doing this
FVector FCylinderIntersection::FindClosestPointOnAxis(const FVector& PointOfInterest, const FVector& CylinderCenter, const FVector& CylinderAxis)
{
FVector NormalizedCylinderAxis = CylinderAxis.GetSafeNormal();
float d = FVector::DotProduct(NormalizedCylinderAxis, PointOfInterest - CylinderCenter);
FVector ClosestPointOnAxis = CylinderCenter + d * NormalizedCylinderAxis;
return ClosestPointOnAxis;
}
bool FCylinderIntersection::IsPointInsideCylinder(const FVector& PointOfInterest, const FVector& CylinderCenter, const FVector& CylinderAxis, float CylinderRadius, float CylinderLength)
{
FVector ClosestPointOnAxis = FindClosestPointOnAxis(PointOfInterest, CylinderCenter, CylinderAxis);
// Check if the point is within the radius of the infinite cylinder
float DistanceToPoint = FVector::Distance(PointOfInterest, ClosestPointOnAxis);
if (DistanceToPoint > CylinderRadius)
{
return false;
}
// Check if the point is within the cylinder of a given length
float DistanceToCenter = FVector::Distance(ClosestPointOnAxis, CylinderCenter);
if (DistanceToCenter > CylinderLength / 2)
{
return false;
}
return true;
}
That, properly exposed as a function library, looks like this:
The input parameters are PointOfInterest (like the Plane Location), CylinderCenter and CylinderAxis (the axis direction).
CylinderAxis is normalized to obtain a unit vector (NormalizedCylinderAxis) as you suggested.
The dot product here is used to find the projection of a vector onto the cylinder’s axis, which finds the closest point on the cylinder’s axis to the given point of interest.
Calculated between NormalizedCylinderAxis and the vector representing the difference between the PointOfInterest and CylinderCenter, which is effectively projecting that difference vector onto the cylinder’s axis.
Then stored in “d”, represents how far (or how much) the closest point is along the cylinder’s axis from the cylinder center.
The ClosestPointOnAxis is then found by adding the ‘d’ multiples of NormalizedCylinderAxis to the CylinderCenter.
Then is later used in the IsPointInsideCylinder() function to determine whether the point is inside the cylinder or not by checking the distance to the closest point and comparing it with the cylinder’s radius and length my friend!