# Projected-2D length of a 3D line?

This topic is 3872 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I need to calculate the length, in pixels, of a 3D line as projected onto screen coordinates. Right now I'm doing the laughably inefficient method of projecting both endpoints (multiplying them with the projection/view/world matrices and the viewport) and getting the length of that 2D line. But I'm sure there's a much simpler method if all I want is the length of that line. Anyone know? EDIT: To clarify, the line is 3D (X/Y/Z coordinates in world-space) and I'm using perspective projection. I do not care about the line's 2D screen coordinates and it's the computation of those that I'm trying to avoid! I care only about how long the line would be if it were projected onto the screen. [Edited by - CGameProgrammer on June 13, 2007 1:28:07 PM]

##### Share on other sites
At the very least you'd need to transform the points into screen-space, and there really isn't a more efficient way than the matrix multiplication. This is because of all the fancy projection math that goes into getting your clip-space coordinates. You can calculate the MVP+Viewport matrix once and then reuse it as long as the camera/window doesn't change. It's then 8 dot products to get the endpoints, and a few more operations to get the length of the vector. This won't necessarily equate to the actual number of rasterized pixels, but it should be close.

It's possible I'm missing something obvious but at the moment I don't see any way around it.

##### Share on other sites
Affine transformation of the source vector doesn't affect its length in the domain of a linear projection, so you can cut your matrix multiplication quota down from two to one. Suppose P is the projection operator and u, v are the endpoints of the line in world-space.
l = |Pu - Pv|  = |P(u - v)|  = |Pw|
So calculate the displacement vector w = u - v, project that, then compute its length.

##### Share on other sites
It's perspective transformation, Admiral. That trick won't work here.

Zipster, you may be right and premultiplying the three matrices may be the only thing I can really do.

But I wonder. Surely there's a way it can be done based off the angle between the two points? Take the ray from the camera to each endpoint and get the dot-product between those lines. It seems like there'd be some way this value can be used to determine the size of the line in screen space.

##### Share on other sites
maybe...

keep the projection matrix, but use the delta vector instead.

[A.x A.y A.z 1]
and
[B.x B.y B.z 1]

transform
D = B - A
[D.x D.y D.z 0]

the w=0 might bring some nice optimisations.

note : not sure this will work, but it should be easy to test quickly and see if you come up with the same result.

edit : hmm, seems like what Admiral says.

##### Share on other sites
There is no W because it's a 3D line. It has X,Y,Z. And I'm using perspective transformation so no, that doesn't work. A line is larger when it's near the camera than when it' farther away.

##### Share on other sites
What's so bad about transforming the end points anyway? If you premultiply your matrices it's just two vector transformns, which is hardly a huge amount of maths.

##### Share on other sites
I think the most efficient way would be to get a ray from the camera position to each line endpoint. Intersect both those rays with the Near Plane (in world space), and then take the length between the resulting Near Plane points. That should be a bit less math-heavy than the full matrix projection.

[Edited by - Waramp81 on June 15, 2007 5:05:25 PM]

##### Share on other sites
I think Waramp81 has a good suggestion. Matrix multiplies are fast if using hardware, but matrix multiplies are a lot of multiplications. Use the similar triangles derivation to get a more efficient way to calculate each component.

##### Share on other sites
Quote:
 Original post by CGameProgrammerI care only about how long the line would be if it were projected onto the screen.

So, to go one step further, does it matter if only part of, or even none of, the line would actually be rendered? Or is it that you only want the length of the line, as it would appear on the screen, and only of the portion that would appear on the screen?

##### Share on other sites
Waramp's suggestion won't work for various reasons -- projection is spherical, not linear, his idea ignores field of view, etc.

Screen-boundary culling shouldn't be needed.

I'll explain the actual situation: What I'm doing is I'm drawing a 3D line at a constant 2D thickness. The line is a polygonal flat mesh along obviously its direction vector, and the cross-product of that with the ray from the camera to the line, so it always faces the camera. And I need its thickness at every point to be, say, 10 pixels wide as an example. So I project the four endpoints to get the actual screen width at both ends, and scale it up accordingly.