[ 
https://issues.apache.org/jira/browse/PDFBOX-1960?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13923921#comment-13923921
 ] 

John Hewson edited comment on PDFBOX-1960 at 3/7/14 4:19 PM:
-------------------------------------------------------------

Maruan, I assure you that you're not understanding the matrix multiplications 
correctly. I didn't say that they are "doing the exact same thing", I said they 
are "doing the exact same thing, just transposed", which they are.

Performing a pre-multiplication on a matrix is the same as performing a 
post-multiplication on its transposition. So the operations you mention are 
identical, your coordinate transformation for PDF is correct, here it is 
written out in full:

{code}
                      [  a  b  0  ] 
[x' y' 1] = [x y 1] . [  c  d  0  ]
                      [  e  f  1  ]  
{code}

But your coordinate transformation for AffineTransform is not, the actual 
[transform|http://docs.oracle.com/javase/7/docs/api/java/awt/geom/AffineTransform.html#concatenate(java.awt.geom.AffineTransform)]
 is as follows:

{code}
[ x']   [  a  c  e  ]   [ x ]  
[ y'] = [  b  d  f  ] . [ y ]
[ 1 ]   [  0  0  1  ]   [ 1 ]
{code}

The values of x' and y' will always be the same in both cases because the 
bottom matrix is just the transposition of the top matrix, but because the 
order of the operations (pre/post multiply) is also switched everything 
continues to works as expected.

Just in case you're still not sure, here are the two transforms on Wolfram 
Alpha:

[Matrix|https://www.wolframalpha.com/input/?i=%7Bx1%2Cy1%2C1%7D+%3D+%7Bx%2Cy%2C1%7D+*+%7B%7Ba%2Cb%2C0%7D%2C%7Bc%2Cd%2C0%7D%2C%7Be%2Cf%2C1%7D%7D]
 results in a row vector and 
[AffineTransform|http://www.wolframalpha.com/input/?i=%7B%7Bx1%7D%2C%7By1%7D%2C%7B1%7D%7D+%3D+%7B%7Ba%2Cc%2Ce%7D%2C%7Bb%2Cd%2Cf%7D%2C%7B0%2C0%2C1%7D%7D+*+%7B%7Bx%7D%2C%7By%7D%2C%7B1%7D%7D]
 results in a column vector, but the values of the variables are the same: _x1 
= a x + c y + e_ and _y1 = b x + d y + f_.

*Conclusion*: Matrix and AffineTransform are directly compatible which is why 
we get the same results when using them. The only alteration that one needs to 
make is to use "conctanate" where the PDF spec says "premultiply" because this 
corrects for the transposition. Do you see how it works?


was (Author: jahewson):
Maruan, I assure you that you're not understanding the matrix multiplications 
correctly. I didn't say that they are "doing the exact same thing", I said they 
are "doing the exact same thing, just transposed", which they are.

Performing a pre-multiplication on a matrix is the same as performing a 
post-multiplication on its transposition. So the operations you mention are 
identical, your coordinate transformation for PDF is correct, here it is 
written out in full:

{code}
                      [  a  b  0  ] 
[x' y' 1] = [x y 1] . [  c  d  0  ]
                      [  e  f  1  ]  
{code}

But your coordinate transformation for AffineTransform is not, the actual 
[transform|http://docs.oracle.com/javase/7/docs/api/java/awt/geom/AffineTransform.html#concatenate(java.awt.geom.AffineTransform)]
 is as follows:

{code}
[ x']   [  a  c  e  ]   [ x ]  
[ y'] = [  b  d  f  ] . [ y ]
[ 1 ]   [  0  0  1  ]   [ 1 ]
{code}

The values of x' and y' will always be the same in both cases because the 
bottom matrix is just the transposition of the top matrix, but the order of the 
operations (pre/post multiply) is also switched.

Just in case you're still not sure, here are the two transforms on Wolfram 
Alpha:

[Matrix|https://www.wolframalpha.com/input/?i=%7Bx1%2Cy1%2C1%7D+%3D+%7Bx%2Cy%2C1%7D+*+%7B%7Ba%2Cb%2C0%7D%2C%7Bc%2Cd%2C0%7D%2C%7Be%2Cf%2C1%7D%7D]
 results in a row vector and 
[AffineTransform|http://www.wolframalpha.com/input/?i=%7B%7Bx1%7D%2C%7By1%7D%2C%7B1%7D%7D+%3D+%7B%7Ba%2Cc%2Ce%7D%2C%7Bb%2Cd%2Cf%7D%2C%7B0%2C0%2C1%7D%7D+*+%7B%7Bx%7D%2C%7By%7D%2C%7B1%7D%7D]
 results in a column vector, but the values of the variables are the same: _x1 
= a x + c y + e_ and _y1 = b x + d y + f_.

*Conclusion*: Matrix and AffineTransform are directly compatible which is why 
we get the same results when using them. The only alteration that one needs to 
make is to use "conctanate" where the PDF spec says "premultiply" because this 
corrects for the transposition. Do you see how it works?

> Matrix and AffineTransform have confusing differences
> -----------------------------------------------------
>
>                 Key: PDFBOX-1960
>                 URL: https://issues.apache.org/jira/browse/PDFBOX-1960
>             Project: PDFBox
>          Issue Type: Improvement
>    Affects Versions: 2.0.0
>            Reporter: John Hewson
>            Priority: Minor
>
> I've been driven insane recently by trying to get pattern fills to render 
> correctly. Patterns have their own matrix which is concatenated to the CTM 
> and no matter how I applied the transformation, the results were wrong.
> It turns out that org.apache.pdfbox.util.Matrix is not behaving as expected, 
> here's an example from a pattern I'm working on. I performed the same 
> concatenation (i.e. multiplication) using our Matrix and Java's 
> AffineTransform, the results are as follows:
> Java AffineTransform:
> [[2.0, 0.0, 1.251E-12], [0.0, 2.0, 1684.0]] *
> [[0.6, 0.0, 302.6], [0.0, 0.6, 1091.38]] =
> [[1.2, 0.0, 605.2000000000013], [0.0, 1.2, 3866.76]]
> PDFBox Matrix:
> [[2.0,0.0,0.0][0.0,2.0,0.0][1.251E-12,1684.0,1.0]] *
> [[0.6,0.0,0.0][0.0,0.6,0.0][302.6,1091.38,1.0]] =
> [[1.2,0.0,0.0][0.0,1.2,0.0][302.6,2101.78,1.0]]
> I suggest that we remove Matrix and replace it with AffineTransform.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to