This should be a useful topic in Advanced Help.
Anyone with questions or opinions on the subject could post here..
3D Vector Math
Re: 3D Vector Math
To kick it off, I thought this would be a good example of what I'd like to have found here:
Common Game Vector Math Tricks..
If you ever looked for ways to find
"The Closest Distance to a Given Finite Line Segment from a Given Point"
or "The Closest Distance from a Given Point to a Given Plane" and found nothing but
insane looking sets of formulae or useless C++ snippets, then this should lay your
questions to rest.
I had almost exhausted what Google offered on the subject and finally decided to come up with my own recipe.
(partly based on those very Google results off-course)
These functions should be quite useful not only in C++ but also in GLSL or HLSL.
(with minor variable type renaming like vec3 or Float3)
Here is a picture of a "Mockup" done In Blender (see the actual C++ functions further down)
Common Game Vector Math Tricks..
If you ever looked for ways to find
"The Closest Distance to a Given Finite Line Segment from a Given Point"
or "The Closest Distance from a Given Point to a Given Plane" and found nothing but
insane looking sets of formulae or useless C++ snippets, then this should lay your
questions to rest.
I had almost exhausted what Google offered on the subject and finally decided to come up with my own recipe.
(partly based on those very Google results off-course)
These functions should be quite useful not only in C++ but also in GLSL or HLSL.
(with minor variable type renaming like vec3 or Float3)
Here is a picture of a "Mockup" done In Blender (see the actual C++ functions further down)
Last edited by Vectrotek on Sat Dec 05, 2015 9:21 pm, edited 1 time in total.
Re: 3D Vector Math
Here are FOUR VERY USEFULL FUNCTIONS..
Code: Select all
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// 001..
vector3df GetClosestPointOnLineSegment (vector3df TestPoint , vector3df LineStart, vector3df LineEnd)
{f32 TheLineModule = 0.0f;
f32 TheDotProduct = 0.0f;
vector3df VectorPrimary;
vector3df VectorSecondary;
vector3df VectorTertiary;
vector3df ClosestCheckPoint;
vector3df Deltas;
// -------------------------------- ---- --- -- -
VectorPrimary = TestPoint - LineStart;
Deltas = LineEnd - LineStart;
TheLineModule = sqrt(( Deltas.X * Deltas.X) + ( Deltas.Y * Deltas.Y ) + ( Deltas.Z * Deltas.Z));
VectorSecondary = Deltas / TheLineModule; // Like Multiplication, Division of vector3df by a float is also legal..
TheDotProduct = ((VectorPrimary.X * VectorSecondary.X)
+(VectorPrimary.Y * VectorSecondary.Y)
+(VectorPrimary.Z * VectorSecondary.Z));
// SEGMENT EDGES ARE CLOSER THAN ANY OTHER POSITION ON THE LINE..
if (TheDotProduct <= 0) return LineStart;
if (TheDotProduct >= TheLineModule) return LineEnd;
// Segment edges tested and failed so continue with calculation..
VectorTertiary = VectorSecondary * TheDotProduct; // See how this statement is legal..
ClosestCheckPoint = LineStart + VectorTertiary;
return ClosestCheckPoint;
}
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// 002..
f32 GetClosestDistanceToLineSegment (vector3df TestPoint , vector3df LineStart, vector3df LineEnd)
{f32 TheLineModule = 0.0f;
f32 TheDotProduct = 0.0f;
vector3df VectorPrimary;
vector3df VectorSecondary;
vector3df VectorTertiary;
vector3df ClosestCheckPoint;
vector3df Deltas;
f32 TheClosestDistance;
// -------------------------------- ---- --- -- -
VectorPrimary = TestPoint - LineStart;
Deltas = LineEnd - LineStart;
TheLineModule = sqrt(( Deltas.X * Deltas.X)
+ ( Deltas.Y * Deltas.Y )
+ ( Deltas.Z * Deltas.Z));
VectorSecondary = Deltas / TheLineModule; // Like Multiplication, Division of vector3df by a float is also legal..
TheDotProduct = ((VectorPrimary.X * VectorSecondary.X)
+ (VectorPrimary.Y * VectorSecondary.Y)
+ (VectorPrimary.Z * VectorSecondary.Z));
// SEGMENT EDGES (either Start OR End) ARE CLOSER THAN ANY OTHER POSITION (Perpendicular) ON THE LINE..
if (TheDotProduct <= 0)
{vector3df DeltasStartTest = LineStart - TestPoint;
return sqrt((DeltasStartTest.X * DeltasStartTest.X)
+ ( DeltasStartTest.Y * DeltasStartTest.Y )
+ ( DeltasStartTest.Z * DeltasStartTest.Z));
}
if (TheDotProduct >= TheLineModule)
{vector3df DeltasEndTest = LineEnd - TestPoint;
return sqrt(( DeltasEndTest.X * DeltasEndTest.X)
+ ( DeltasEndTest.Y * DeltasEndTest.Y )
+ ( DeltasEndTest.Z * DeltasEndTest.Z));
} // And skip all else..
// Segment edges tested and failed so continue with calculation..
VectorTertiary = VectorSecondary * TheDotProduct; // See how this statement is legal..
ClosestCheckPoint = LineStart + VectorTertiary;
vector3df DeltasClosestTest = ClosestCheckPoint - TestPoint;
return sqrt((DeltasClosestTest.X * DeltasClosestTest.X)
+ (DeltasClosestTest.Y * DeltasClosestTest.Y)
+ (DeltasClosestTest.Z * DeltasClosestTest.Z));
}
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// 003.. Aquiring the NORMAL & POSITION for a PLANE is as simple as
// GERATING a NORMAL from a SELECTED TRIANGLE and
// using ANY ONE of its POINTS as the PLANE POSITION..
vector3df GetClosestPointOnPlaneFromPoint (vector3df TestPoint ,
vector3df PlanePos,
vector3df PlaneNormal) // NORMAL MUST BE NORMALISED!!
{f32 TheLineModule = 0.0f;
f32 TheDotProduct = 0.0f;
vector3df VectorPrimary;
vector3df VectorTertiary;
vector3df ClosestCheckPoint;
vector3df PlaneDeltas;
// vector3df ToPlaneDeltas;
vector3df ClosestPointOnPlane;
f32 DistanceToPlane;
// -------------------------------- ---- --- -- -
VectorPrimary = TestPoint - PlanePos; // See how the Plane Pos is also the start of the Normal for the Plane..
TheDotProduct = ((VectorPrimary.X * PlaneNormal.X)
+ (VectorPrimary.Y * PlaneNormal.Y)
+ (VectorPrimary.Z * PlaneNormal.Z));
VectorTertiary = PlaneNormal * TheDotProduct; // See how this statement is legal.
ClosestCheckPoint = PlanePos + VectorTertiary;
PlaneDeltas = ClosestCheckPoint - PlanePos;
ClosestPointOnPlane = TestPoint - PlaneDeltas; // By a simple geometric analysis.. (Blender Mockups)
return ClosestPointOnPlane;
}
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// 004..
f32 GetDistanceToPlaneFromPoint (vector3df TestPoint ,
vector3df PlanePos,
vector3df PlaneNormal) // NORMAL MUST BE NORMALISED!!
{f32 TheLineModule = 0.0f;
f32 TheDotProduct = 0.0f;
vector3df VectorPrimary;
vector3df VectorTertiary;
vector3df ClosestCheckPoint;
vector3df PlaneDeltas;
vector3df ToPlaneDeltas;
vector3df ClosestPointOnPlane;
f32 DistanceToPlane;
// -------------------------------- ---- --- -- -
VectorPrimary = TestPoint - PlanePos; // See how the Plane Pos is also the start of the Normal for the Plane..
TheDotProduct = ((VectorPrimary.X * PlaneNormal.X)
+ (VectorPrimary.Y * PlaneNormal.Y)
+ (VectorPrimary.Z * PlaneNormal.Z));
VectorTertiary = PlaneNormal * TheDotProduct;
ClosestCheckPoint = PlanePos + VectorTertiary;
PlaneDeltas = ClosestCheckPoint - PlanePos;
ClosestPointOnPlane = TestPoint - PlaneDeltas;
ToPlaneDeltas = ClosestPointOnPlane - TestPoint;
DistanceToPlane = sqrt((ToPlaneDeltas.X * ToPlaneDeltas.X)
+ (ToPlaneDeltas.Y * ToPlaneDeltas.Y)
+ (ToPlaneDeltas.Z * ToPlaneDeltas.Z));
return DistanceToPlane;
}
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// These Functions can be greatly optimised so that'll be a nice exercise for you! They DO WORK THOUGH..
Jacques Pretorius 2015..
Last edited by Vectrotek on Sat Dec 05, 2015 9:24 pm, edited 2 times in total.
Re: 3D Vector Math
Here is a screenshot of experiments in normal Math Notation before converting it to C++..
Re: 3D Vector Math
This started with with me trying to find a way to do "Plane Based Fog" i.e. Fog effect based on the distance of a fragment from a given plane for spooky effects..
Re: 3D Vector Math
Thank you Vectrotek, that will come handy
Re: 3D Vector Math
Awesome work! Maybe you can extend the functionality of the lines and planes with all those operations, or optimize the current implementations
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt