so we have our 3x3 rotation/translation matrix A -

[ 1 .0747 0 ] [ -.0747 1 0 ] [ .2817 -.4486 1 ]

the rotation-only part, A(1:2,1:2), has singular value decomposition

U = [ -.9972 .0745 ] [ .0745 .9972 ] S = [ 1.0028 0 ] [ 0 1.0028 ] V = [ -1 0 ] [ 0 1 ]

which amounts to, in order, a y-axis flip, a scale in both x- and y-directions by 1.0028, and a second y-axis flip coupled with a .0749 radian rotation. this doesn't get us quite there, though, because we still need to apply the translation from the original A matrix, which is x+.2817, y-.4486. but applying this directly doesn't work. why.

in fact, [2 2]*V*S*U overestimates in both the x and y coordinates, whereas [2 2 1]*A gives the exact coordinates from the source file. this is really weird, especially considering

U*S*V = [ 1 .0747 ] [ -.0747 1 ]

which is exactly equal to the top left corner of A.

ahh.

because of how we constructed A - that is, so that x0*A = x1, to find the image of a point p under the SVD of A, we have to take p*(USV), not p*(VSU) as originally thought. then you take this rotated/scaled version of the points and apply the above translations, and everything's hunky-dory.

okay.

so how do we get this information out of SVD? we can grab the translation stuff right out of A, that's straightforward. but how to balance that with rotations and scaling to get something accurate?

generally the SVD is going to give a big rotation in one direction and a big rotation in the other, along with a little bit of scaling but probably not much in our cases.

so let's start out with how to get the translation arrow, since we can get that directly from A.

we can just call A(3,1:2)' the vector we need to superimpose on the image, and maybe scale it a little bit. but we're not putting it at the origin, because that's meaningless; we should put it in the middle of the cluster whose translation this is -- but we should also put it against the side closest to the direction of the vector, so it doesn't get lost amongst the points of the cluster.

- calculate center of x0 cluster.
- determine direction of translation vector - more toward +/- x/y?
- move origin of vector to most extreme surface/point in direction from (2).
- scale?

potential problem: what if the direction from (2) lands the vector inside the total molecule - what if the translation on the whole molecule is +x, but the far left portion of the molecule has its own cluster? or if we have multiple squishing/expanding sections, and indicating this would put an arrow inside a molecule, losing the information?

solution: check for interfering sections? if an interfering section exists, check in a secondary direction (+/-y, in this case), and if either is clear, move it to there.

potential problem: in our bar case, what if we have a translation mostly +x but some -y. the above algorithm would place the arrow on the +x end of the bar, but does that imply stretching more than translation? would it be more communicative to place the arrow underneath the bar, but towards the +x side?

a lot of the problems i'm running into in my head involve the inherent shape of the molecule/cluster in question. how can we integrate that information into our choice of where to place the arrow best?

--> can we use different types of arrows to communicate different things? since we're rendering, can we use flat arrows for one thing, round for another, ==> double arrows for something else? how about the curved bottoms i mentioned to yoh? what do each of these arrow types imply to an untrained viewer? can we fix that with thickness, length, color, or some other attribute?

okay, so for a translation, we want an arrow that starts within the cluster and proceeds outside, possibly just a tube outline? definitely something flat. so we DO want to have it come out of the center of x0, and we'll have to scale it so that it sticks out of the cluster. the width of the arrow should be proportional to the dimension of the cluster, and the scaling of the vector length should be proportional to the thickness of the cluster.

width - 1/7?

scaling - add center-to-surface only?

**so calculate translation vector first, and we'll build from there.**

now we have a translation vector, appropriately positioned and blah blah blah. to get the SVD, we chop off the 3rd row and column of A and take [U,S,V] = svd(A). by what we have in the graphics book, U and V are rotation matrices, and S is the scaling matrix. the problem here is how to tell what the overall effect of this is. in two dimensions we're looking at a 2x2 matrix, four entries, and one of them is going to have a different sign, due to either rotational stuff or flipping.

--> how to cluster? optimization problem - try to find clusters to minimize error (x0*A - x1).

also for arrows: use matrix exponentiation and track p0-p1 for three "close" points in a cluster, throw a surface between the paths and call it an arrow. or use short transform and do it for 10*A or something.