Started by Jan 29 2013 01:33 PM

,
10 replies to this topic

Posted 29 January 2013 - 01:33 PM

I have a line (with points A, B on the line), and a distance 'h' to a parallel line. Under an affine transformation, the lines should stay parallel, but the distance between them might change. How can I get the new distance between the lines?

My thinking right now is to construct a point on the red line, transform that point with the affine transformation, and then find the distance of that new point to the transformed black line AB. But is there a more direct way to calculate the new distance?

Darwinbots - Artificial life simulation

Posted 29 January 2013 - 02:03 PM

I don't understand how there could be a more direct measurement, unless you're looking for an equation.

According to the definition from wolfram, an affine transformation is one that "preserves collinearity ... and **ratios of distances**."

Thus if you're scaling everything, the distance will scale with the lines as well. Thus new h = old h * scale amount. Otherwise the h will stay the same.

Hope this helps,

Selenaut

Posted 29 January 2013 - 02:16 PM

That wording of "ratios of distances" is misleading. It only works for distances measured along the same line.

The only methods I can think of are essentially the same as what Numsgil came up with.

The only methods I can think of are essentially the same as what Numsgil came up with.

Posted 29 January 2013 - 02:17 PM

The distance can be seen as the length of a direction vector **d**. The vector can be transformed as well, and the length of the vector after transformation is the distance of the lines after transformation.

Let d := |**d**| be the original length.

Uniform scaling **S** * **d** =: **d**' will cause d' = s * d, that's right. However, non-uniform scaling isn't that simple, because the direction of **d** plays a role. Moreover, if the transformation in question is a composite one w.r.t. the well known primitive transformations, then **S** is perhaps applied in a space where the direction of **d** isn't the same as those it is computed initially.

I think that for the most general case the transformation must be applied.

Posted 29 January 2013 - 02:42 PM

Yeah, I dunno *too *much about affine transformations, I was kinda taking a stab in the dark there (just another example of how assumptions suck).

However, as haegarr stated, I think you answered your own question.

Posted 29 January 2013 - 03:07 PM

Affine transformation is just another name for a matrix with non uniform scale, rotation, and translation baked in (more or less). I didn't mean to be too obtuse when forming the question

Anyway, I came up with: h' = h * length(S*(b - a)) / (length(b - a)) after a bit of algebra. Can someone confirm/refute that? I took the method I described and worked it out algebraically. But intuitively I'm surprised I'm using b-a and not a vector perpindicular to b-a or something along those lines.

Darwinbots - Artificial life simulation

Posted 29 January 2013 - 04:15 PM

h' = h * length(S*(b - a)) / (length(b - a))

Um... Aren't you just multiplying by S then?

Think about what that says in plain english: The new 'h' is the old 'h' times the scaled length of a line, divided by the length of the same line.

**Edited by Ravyne, 29 January 2013 - 04:16 PM.**

throw table_exception("(ノ ゜Д゜)ノ ︵ ┻━┻");

Posted 29 January 2013 - 04:20 PM

That's true if S is a scalar, but not if S is a matrix.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Posted 29 January 2013 - 05:04 PM

Let points X and Y be arbitrary closest point pairs on the two lines. That is, X lies on the first line, and Y lies on the second line, and the distance between those two points is the same as the distance of the two lines themselves, i.e. in the original picture, h = |X-Y|.

Let H := X-Y =: (x,y,z,0). That is, H is a direction vector between the two points and it's length |H| = h is the distance between the two lines.

Let A be the affine map in question. Since A is affine, it is representible by a matrix M, using operation A(v) = M*v.

Then the sought new distance is

h' = |A(H)| = |M*H|

If the affine map A does contain shear and therefore M is not guaranteed to be orthonormal, then one can't do much better than to compute the matrix multiplication above.

If the affine map A does not contain any shearing, the formula does simplify: For ease of notation, fix ourselves to a 3D space (although 2D or other dimensions are equivalent). We can decompose the matrix M to a form M = N*S, where S is a diagonal matrix S=diag(sx,sy,sz,1) and N consists of column vectors vx,vy,vz,t, where vx, vy and vz are normalized and t is a translation component. That is, decompose the scaling part out of matrix M to matrix S.

Since A does not contain any shearing, the matrix N is orthonormal (only rotates, and potentially mirrors and its determinant is +/-1), and the new distance is

h' = |M*H| = |N*S*H| = |S*H| = |(sx*x,sy*y,sz*z)|

Me+PC=clb.demon.fi | C++ Math and Geometry library: MathGeoLib, test it live! | C++ Game Networking: kNet | 2D Bin Packing: RectangleBinPack | Use gcc/clang/emcc from VS: vs-tool | Resume+Portfolio | gfxapi, test it live!

Posted 29 January 2013 - 06:15 PM

@clb: I don't think you can do h' = |M*H| because M*H is not guaranteed to be a shortest path between the two parallel lines after they're transformed by M.

That is, just because H is perpendicular to both lines before transformation doesn't mean it's perpendicular to both lines after transformation. Consider the case of a sheering of a square in to a parallelogram. One of those funny properties of affine transformations: closest point pairs on parallel lines aren't preserved.

Darwinbots - Artificial life simulation

Posted 30 January 2013 - 01:23 PM

Numsgil: You are absolutely correct.

For the case of no shear, it should hold. For the case with shear, I think it's possible to arrive to a closed expression by deriving the distance between the lines under the operation by the affine map, but that's indeed a more detailed examination.

Me+PC=clb.demon.fi | C++ Math and Geometry library: MathGeoLib, test it live! | C++ Game Networking: kNet | 2D Bin Packing: RectangleBinPack | Use gcc/clang/emcc from VS: vs-tool | Resume+Portfolio | gfxapi, test it live!