3

I have two array of points:

Point [] original; AND Point [] transformed;

These transformed array is simply a copy of the original with transformations applied. Example:

matrix.Rotate(5f);  
matrix.Scale(.8f, 1.1f);  
matrix.Translate(30f, 18f);  
matrix.TransformPoints(transformed);
  • The original points ARE known.
  • The transformation values ARE known.
  • The order in which the transformations were applied is NOT known.

How can I calculate / infer the order of transformations?

EDIT

  • There is only ONE round of transformation.
  • A round could contain at most three transformations as below.
  • The only transformations applied are any combination on rotate, scale and translate.

To give it some real-world context, consider having an image with known points of interest. You print the image, scan it and try to read it again. The image contains orientation markers that allow me to calculate the transformations applied during the scanning process.

Now, a brute force approach would be:

  1. Read scanned image.
  2. Calculate rotation on the scanned image.
  3. Apply rotation on the scanned image.
  4. Calculate scale on the rotated image.
  5. Apply scale on the rotated image.
  6. Calculate translation on the scaled image.
  7. Apply translation on the scaled image.

You can now read the points of interest from the processed image using the original points as if there was no transformation. Of course this method is expensive. A 500MB image would need to have at least two copies in memory at a time and would have to be transformed using the graphics object.

The premise of this question was to read the image only once, calculate all transformations and apply them to coordinates rather than the image itself. The use the transformed coordinates to read the points of interest. This is where the problem of 'order of transformations' comes in. Some very helpful answers below and I hope this clears the context.

Raheel Khan
  • 14,205
  • 13
  • 80
  • 168
  • 1
    How many transforms do you have? It occurs to me that unless it is a heck of a lot a brute force approach is going to be easiest and best. If you have a lot I think you may still need a brute force approach without some pretty complicated analysis of things... Also you are not guaranteed to find a unique solution (eg two translates consecutively could be reversed). – Chris Jan 12 '12 at 11:11
  • I dont think you can work this out. For example, the Translate function could be performed at any step with the end result being the same – musefan Jan 12 '12 at 11:13
  • 1
    @Musefan: that's not actually true of the translate. Imagine your first point is `0,1` and that your two transforms are a translation by `0,-1` and a rotation of 180 degrees about the origin. Clearly it is important whether you do the translation before the rotation. same argument applies to scaling too. – Chris Jan 12 '12 at 11:16
  • @Chris: You are right, I had assumed the origin point was relative to the object (say the center point)... given the context, I admit this was probably not the best assumption to be making ;) – musefan Jan 12 '12 at 11:17
  • @Chris: There will only be one single round of transformation that may or may not include rotation, scale and translation. Original points are known. Transformed points are known. Even transformation values are known! Even a brute force approach should not be expensive at all. I'm just struggling with it due to unfamiliarity. – Raheel Khan Jan 12 '12 at 11:31
  • @RaheelKhan: Could you clarify what you mean by a round? Does a round only include at most one of each transformation or can it include multiples of each type? Are your only transformations those three (rotation, scale and translation)? – Chris Jan 12 '12 at 11:36
  • @Chris: A round would only include at most one of each. And, yes, the transformation types only include those three. – Raheel Khan Jan 12 '12 at 11:53
  • Do you have code or documentation of what transformed the points? –  Jan 12 '12 at 12:31
  • @Nocturn: Not code but I have edited the question to give you exact context. That should clear it up. Also, have a look at my last comments on Chris' answer. – Raheel Khan Jan 12 '12 at 17:52

2 Answers2

1

For the number of transformations that you are looking at brute force is probably the easiest approach rather than trying to do any mathematical analyses on things (I'm not 100% sure if that's even possible but it would be very hard).

For three different transforms (A,B,C) you have six different ways you can apply them. They are:

  • ABC
  • ACB
  • BAC
  • BCA
  • CAB
  • CBA

So for each of those apply them in that order to your input and check whether the final product matches your output.

If you don't have one of the specific transforms then you are left with only two options of order. This may be best dealt with by just using the above six options and applying an identity matrix (or a no-op) where the missing transform is. Of course you also need checks to prevent you from duplicating the same transform order.

For optimal performance you don't necessarily need to check all the points in your array - if the first point doesn't match then no need to check any more. You will of course want to check all of the points in the array for any that match to ensure that its not just by chance that the first point transformed that works. Also you can check for trivial transformations (such as scale by a factor of 1) and treat them as not existing because they could appear at any position at all so you might as well assume they are at the beginning (or end or middle - personal preference).

Lastly there is still a possibility of ambiguity. its not very likely and with even a small set of input points it becomes very unlikely. It is a point you need to be aware of though. Also see below for discussion on special case where ambiguity becomes a lot more likely.

I hope this is enough to get you going in the right direction. I can't write full code because I have no idea how your transformation data is stored and so on.

After some brief discussion about whether certain translation are commutative or not (eg is doing A then B the same as doing B then A) I believe that they are not. In the special case where the scaling of X and Y are equal then scaling and rotation are commutative but the syntax used here suggests that scaling has two factors that I presume to be X and Y scale factors. This means that scaling and rotation are not commutative in this case. Translations are never commutative (imagine the trivial case where a translation would move the point to the origin and you can see that it matters).

Nocturn's point (in comments) on commutativity does apply though if the scale is the same on X and Y axes. This means that if you have such a scale and it is next to a rotation then you will get two possible transformation orders that are valid. There will be no way to distinguish between the two.

Chris
  • 27,210
  • 6
  • 71
  • 92
  • 2
    @Nocturn: the sample code by the OP has two parameters passed to the scale method so I assume it can scale differently in X and Y in which case scaling and rotation aren't commutative. Also making assumptions about where translations are sounds unwise when the whole point of the question is to find where they are. Better to assume they could be anywhere and actually check. – Chris Jan 12 '12 at 14:42
  • I think you can only do it if I do an edit or something. I'll edit on a chunk about commutative since we've discussed it. :) – Chris Jan 12 '12 at 15:04
  • @Nocturn: You also made me realise that ambiguity in the case where scale factors are equal is actually quite likely too so thank you for pointing that out. :) – Chris Jan 12 '12 at 15:11
  • @Chris: I have updated the question to give you context. Once you've read that, please tell me if I'm right in assuming that correct order has to be determined. If that has to be the case, then your brute force approach would be the only way. Calculate all non-redundant combinations and match orientation markers to determine the closest match. – Raheel Khan Jan 12 '12 at 17:42
  • @Chris: However, I have a strong feeling that there could be a more reliable approach. After all, if you had the source and scanned images in front of you, you could (without using software) measure the transformations and calculate the transformed points of interest using simple geometry and ratios right? – Raheel Khan Jan 12 '12 at 17:48
  • @RaheelKhan: Its interesting to see the context but sadly I am not sure that I can be any more helpful with it. If you have three points on the page with known position and measurements then you should be able to calculate the transformation I think. Imagine it to be an origin, and then a poitn one unit up the x axis and one up the y-axis. You just need to find a single matrix that transforms this to your final thing. That should just be a series of equations to solve I think (though I am not sure if the algebra will be simple). Its doable by hand easily enough at least... – Chris Jan 13 '12 at 09:36
  • @Chris: Thank you. Both approaches do provide an answer so I have marked your response as accepted. It certainly has been helpful. I'll post my own answer later with the actual implemented solution for those interested. – Raheel Khan Jan 13 '12 at 14:51
  • @RaheelKhan: I'd certainly be interested so if you can put a comment on here with my name in so that I notice I'd appreciate it. ;-) – Chris Jan 13 '12 at 15:01
  • 1
    @Nocturn: Yeah, I wasn't really thinking about the fact that finding the inverse of a matrix isn't actually that hard. ;-) But yes, if I had known start and end points I would do the single matrix approach as you have rather than try to find three separate operations to combine. – Chris Jan 16 '12 at 09:35
  • Your last comment to (Nocturn) seems to sum up my question pretty well. This is driving me crazy because I am sure the answer lies in basic geometry and I can't find it. I've launched yet another question [here](http://stackoverflow.com/questions/8959657/order-sequence-of-matrix-transformations-in-2d) to try and figure it out. If I can achieve the objective in three steps, there HAS to be a way to normalize it to a single geometric function! – Raheel Khan Jan 22 '12 at 07:31
0

in CG it's quite common to hold a Matrix Stack, i.e. each time you perform an operation on the matrix (transform, rotate, or scale), you put the new Matrix to a stack. this way you can track-back to your original state.

Shai
  • 25,159
  • 9
  • 44
  • 67
  • Recording them as you go along is of course a good way to know the order but I assume that this is not an option in this case since it would trivialise the question. Though of course why he has the information he does and not know the order is a different matter. :) – Chris Jan 12 '12 at 11:13
  • That is certainly a different matter :). You can have a look [here](http://stackoverflow.com/questions/8815223/matrix-coordinate-transformation-in-c-sharp) for reference. I did not want to mix questions and make them complicated. I have no control over the order in which they are applied. – Raheel Khan Jan 12 '12 at 11:27