I am trying to calculate the perpendicular vector to a dynamic direction in vex but so far I just cant get it to work. Cross product came to mind but then I would need two vectors to calculate the perpendicular, but in this case I just have one direction from pt0 to pt1.
VEX - Calculating perpendicular vector to given direction
1404 18 2-
- Kareeem
- Member
- 90 posts
- Joined: 10月 2021
- Offline
Hey there,
I am trying to calculate the perpendicular vector to a dynamic direction in vex but so far I just cant get it to work. Cross product came to mind but then I would need two vectors to calculate the perpendicular, but in this case I just have one direction from pt0 to pt1.
I am trying to calculate the perpendicular vector to a dynamic direction in vex but so far I just cant get it to work. Cross product came to mind but then I would need two vectors to calculate the perpendicular, but in this case I just have one direction from pt0 to pt1.
Edited by Kareeem - 2025年2月28日 08:05:39
-
- Tanto
- Member
- 502 posts
- Joined: 11月 2016
- Offline
There is an infinity of vectors perpendicular to your direction. Cross product is indeed what you need. If any perpendicular vector will do, just use any vector as the second argument of your cross product. If you need a specific one, try to figure out on which plane you want it to be and use the normal of that plane as your second cross product vector.
This [en.wikipedia.org] might be of help.
This [en.wikipedia.org] might be of help.
Edited by Tanto - 2025年2月28日 10:00:56
-
- animatrix_
- Member
- 4857 posts
- Joined: 2月 2012
- Offline
Hi,
You can do it like this:
You can do it like this:
vector getPerpendicularVector ( vector v ) { vector vn = normalize ( v ); vector vu = abs ( vn.x ) < abs ( vn.z ) ? { 1, 0, 0 } : { 0, 0, 1 }; return normalize ( cross ( vn, vu ) ); }
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com] https://lnk.bio/animatrix [lnk.bio]
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com] https://lnk.bio/animatrix [lnk.bio]

-
- vikus
- Member
- 243 posts
- Joined: 5月 2017
- Offline
-
- Kareeem
- Member
- 90 posts
- Joined: 10月 2021
- Offline
animatrix_
Hi,
You can do it like this:vector getPerpendicularVector ( vector v ) { vector vn = normalize ( v ); vector vu = abs ( vn.x ) < abs ( vn.z ) ? { 1, 0, 0 } : { 0, 0, 1 }; return normalize ( cross ( vn, vu ) ); }
Wow, this seems advanced. I am having trouble understanding even the first line. What is this syntax? A short version for something?
Thanks for taking the time though, much appreciated!
-
- Kareeem
- Member
- 90 posts
- Joined: 10月 2021
- Offline
vikus
This should also workvector n = normalize(set(p.z, 0, -p.x)); addpoint(0, p + n);
This actually works, thanks! I needed to fix it up a bit though

vector n = normalize(set(@P.z, 0, -@P.x)); addpoint(0, @P + n);
I´ll try to figure out what you are doing here ... I mean I get what you are doing but how on earth would one think of that?

Edited by Kareeem - 2025年2月28日 10:27:05
-
- vikus
- Member
- 243 posts
- Joined: 5月 2017
- Offline
-
- Kareeem
- Member
- 90 posts
- Joined: 10月 2021
- Offline
-
- vikus
- Member
- 243 posts
- Joined: 5月 2017
- Offline
-
- Kareeem
- Member
- 90 posts
- Joined: 10月 2021
- Offline
-
- tamte
- Member
- 9124 posts
- Joined: 7月 2007
- Offline
Kareeemyou can also write the same thing as :
This actually works, thanks! I needed to fix it up a bit thoughI´ll try to figure out what you are doing here ... I mean I get what you are doing but how on earth would one think of that?vector n = normalize(set(@P.z, 0, -@P.x));
vector n = normalize( cross( @P, {0,-1,0} ) );
Edited by tamte - 2025年2月28日 12:12:16
Tomas Slancik
CG Supervisor
Framestore, NY
CG Supervisor
Framestore, NY
-
- Kareeem
- Member
- 90 posts
- Joined: 10月 2021
- Offline
tamteKareeemyou can also write the same thing as :
This actually works, thanks! I needed to fix it up a bit thoughI´ll try to figure out what you are doing here ... I mean I get what you are doing but how on earth would one think of that?vector n = normalize(set(@P.z, 0, -@P.x));but once you expand the math of the cross product that's what's leftvector n = normalize( cross( @P, {0,-1,0} ) );
Oh wow, i think I finally got it now. I thought for some reason that the two vectors I feed into the cross product need to be perpendicular to each other to beginn with and if they are not the result of the cross product would also not be perpendicular.
I think this image gave me that idea
-
- Kareeem
- Member
- 90 posts
- Joined: 10月 2021
- Offline
Tanto
There is an infinity of vectors perpendicular to your direction. Cross product is indeed what you need. If any perpendicular vector will do, just use any vector as the second argument of your cross product. If you need a specific one, try to figure out on which plane you want it to be and use the normal of that plane as your second cross product vector.
This [en.wikipedia.org] might be of help.
So you were correct right from the start. I can use any vector as the 2nd argument. How cool is that cross function?!

Edited by Kareeem - 2025年2月28日 14:38:03
-
- animatrix_
- Member
- 4857 posts
- Joined: 2月 2012
- Offline
Kareeemanimatrix_
Hi,
You can do it like this:vector getPerpendicularVector ( vector v ) { vector vn = normalize ( v ); vector vu = abs ( vn.x ) < abs ( vn.z ) ? { 1, 0, 0 } : { 0, 0, 1 }; return normalize ( cross ( vn, vu ) ); }
Wow, this seems advanced. I am having trouble understanding even the first line. What is this syntax? A short version for something?
Thanks for taking the time though, much appreciated!
It's ternary operator [en.m.wikipedia.org].
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com] https://lnk.bio/animatrix [lnk.bio]
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com] https://lnk.bio/animatrix [lnk.bio]

-
- Kareeem
- Member
- 90 posts
- Joined: 10月 2021
- Offline
animatrix_
It's ternary operator [en.m.wikipedia.org].
Hey thanks for clarifying! Although I did not know that term I was aware of the"short version" of the if statement.
But I am still not sure what you are doing in the first line ... Are you creating a custom function here?
Edited by Kareeem - 2025年3月1日 02:40:13
-
- animatrix_
- Member
- 4857 posts
- Joined: 2月 2012
- Offline
Kareeemanimatrix_
It's ternary operator [en.m.wikipedia.org].
Hey thanks for clarifying! Although I did not know that term I was aware of the"short version" of the if statement.
But I am still not sure what you are doing in the first line ... Are you creating a custom function here?
Yes.
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com] https://lnk.bio/animatrix [lnk.bio]
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com] https://lnk.bio/animatrix [lnk.bio]

-
- Kareeem
- Member
- 90 posts
- Joined: 10月 2021
- Offline
animatrix_
Hi,
You can do it like this:vector getPerpendicularVector ( vector v ) { vector vn = normalize ( v ); vector vu = abs ( vn.x ) < abs ( vn.z ) ? { 1, 0, 0 } : { 0, 0, 1 }; return normalize ( cross ( vn, vu ) ); }
I dissected this and wrote it down in vex code I can understand for a detail wrangle and without the custom function. Thank you for the inspiration. I still have a hard time understanding how you can come up with the math but I guess it again comes down to the basic knowledge Vicus posted here as well and experience.
// calc dir from start to end vector start = point(0, "P", 0); vector end = point(0, "P", 1); vector dirn = normalize(end-start); vector diru; // calc math magic if (abs(dirn.x) < abs(dirn.z)) { diru = {1,0,0}; } else{ diru = {0,0,1}; } // export @ v@N = normalize(cross(dirn, diru));
Edited by Kareeem - 2025年3月1日 07:57:49
-
- animatrix_
- Member
- 4857 posts
- Joined: 2月 2012
- Offline
The abs line picks the axis that is least aligned with vn, ensuring the cross product produces a well-conditioned perpendicular vector with a stable magnitude.
If vn is already close to { 1, 0, 0 } (X-axis), then { 1, 0, 0 } is a bad choice for vu because the cross product would produce a very small (almost zero) vector, leading to numerical issues.
If vn is closer to { 0, 0, 1 } (Z-axis), then { 0, 0, 1 } is a bad choice for the same reason.
If vn is already close to { 1, 0, 0 } (X-axis), then { 1, 0, 0 } is a bad choice for vu because the cross product would produce a very small (almost zero) vector, leading to numerical issues.
If vn is closer to { 0, 0, 1 } (Z-axis), then { 0, 0, 1 } is a bad choice for the same reason.
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com] https://lnk.bio/animatrix [lnk.bio]
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com] https://lnk.bio/animatrix [lnk.bio]

-
- Kareeem
- Member
- 90 posts
- Joined: 10月 2021
- Offline
animatrix_
The abs line picks the axis that is least aligned with vn, ensuring the cross product produces a well-conditioned perpendicular vector with a stable magnitude.
If vn is already close to { 1, 0, 0 } (X-axis), then { 1, 0, 0 } is a bad choice for vu because the cross product would produce a very small (almost zero) vector, leading to numerical issues.
If vn is closer to { 0, 0, 1 } (Z-axis), then { 0, 0, 1 } is a bad choice for the same reason.
Nice, thanks for explaining it once again!
-
- Quick Links