glam-rs icon indicating copy to clipboard operation
glam-rs copied to clipboard

[feature] provide a method to project Vec4 and Vec3 from homogeneous space

Open seichter opened this issue 2 years ago • 4 comments

What problem does this solve or what need does it fill?

Currently Vec3 provides extend(w) to unproject into homogeneous coordinates (hence Vec4 with euclidean hyperspace w - maybe I missed it, but there is no inverse to extend() or the documentation misses to mention it.

What solution would you like?

I would prefer to write something like this

transform.translation = view.w_axis.project()

rather than

transform.translation = view.w_axis.xyz() / view.w_axis.w;

My example is now for Vec4 ... same applies to homogeneous representations of Vec2 in vectorspace R3 using Vec3

What alternative(s) have you considered?

Keep writing rather obvious code

This was originally a request in bevy https://github.com/bevyengine/bevy/issues/6916#

seichter avatar Dec 11 '22 16:12 seichter

Naming wise it would be good to make sure there is a clear distinction between this and the existing vector project_onto method.

bitshifter avatar Dec 11 '22 21:12 bitshifter

Agreed, here my 2ct

Eigen is using homogeneous() and hnormalized() which is rather meh and it doesn't allow for w=0

Armadillo has a reshape() and resize() but seems quite dated anyway. Numpy has pythonic syntax-sugar to deal with this. GLM only does projection/unprojection through constructors.

So, I guess there is no common agreement. Maybe shrink() or contract() would work.

seichter avatar Dec 17 '22 20:12 seichter

Still mulling over what to call this. The operation is simple, naming is hard. It seems like this operation is "perspective divide" or "homogeneous divide" or "homogeneous normalization" are common names for this operation. Thus the "hnormalize" in Eigen. Vek calls it "homogenize(d)".

I'm thinking of adding Vec3::from_homogeneous(Vec4) -> Vec3 which performs the divide by w. It would be up to the user to make sure the input was valid (w != 0). Also Vec3::to_homogeneous(self) -> Vec4 which is like Vec3::extend(1.,0). This is what cgmath currently does https://docs.rs/cgmath/latest/cgmath/struct.Point3.html#method.from_homogeneous.

Might also add a Vec4::homogenize() -> Vec4 which returns a Vec4 divided by w.

bitshifter avatar Apr 11 '23 10:04 bitshifter