# xmlgraphics-batik-users mailing list archives

##### Site index · List index
Message view
Top
From "Bishop, Michael W. CONTR J9C880" <michael.bishop....@jfcom.mil>
Subject RE: Tracking changes to the rendering transform?
Date Mon, 06 Oct 2008 19:32:33 GMT
```Hi Thomas and Dan,

Yeah, the agg code declares variables m0 - m5 which I assumed were:

m00 m01 m02
m10 m11 m12

Java constructor uses {m00, m10, m01, m11, m02, m12}.

It's just semantic differences, but to properly understand the C++ code, I need to be sure
what m0 - m5 represent or specifically, what order they are determined in the matrix.

I thought the difference between an AffineTransform and a matrix was that an AffineTransform
was a specific 3x3 matrix used for translate, rotation, etc.

As for the example, yes I think I am lost.

Let me see if I can translate this stuff to Java to avoid matrix representation difficulties.

I get src points:

double[] src = {x1, y1, x2, y2, x3, y3};

mapped into an AffineTransform (at);

double m00 = x2 - x1;
double m10 = y2 - y1
double m01 = x3 - x1;
double m11 = y3 - y1
double m02 = x1;
double m12 = y1;

AffineTransform at = new AffineTransform(new double[] {m00, m10, m01, m11, m02, m12});

Point2D upperLeft = new Point2D.Double(0, 1);
Point2D derivedUpperLeft = at.transform(upperLeft);
derivedUpperLeft.equals(new Point2D.double(x1, y1));  // True?

I don't understand the distinction between (a, b) and (c+e, d+f).  I thought a transformed
point 0,1 through the derived matrix would be the same as the original upper-left point (x1,
y1).  Of course, I probably meant (x1, y1) in my original post, not (a, b) as given to the
matrix.

Dan, thanks for your input.  Yeah, I'm going the long way and trying to encompass it all.
Obviously I'm learning this stuff too, but if I ever get my head around it, you're welcome
to the updated AffineTransformUtil!

Michael

________________________________

From: thomas.deweese@kodak.com [mailto:thomas.deweese@kodak.com]
Sent: Fri 10/3/2008 5:05 PM
To: batik-users@xmlgraphics.apache.org
Cc: batik-users@xmlgraphics.apache.org
Subject: RE: Tracking changes to the rendering transform?

Hi Michael,

"Bishop, Michael W. CONTR J9C880" <michael.bishop.ctr@jfcom.mil> wrote on 10/03/2008
04:36:37 PM:

> > This isn't a proper representation of their matrix.  They store it as...
>
> Who is "they?"

The Agg folks.

> I was going with the example from my SVG book and
> the Java documentation where:
>
> { a, b, c, d, e, f} passed into the constructor comes out:
>
> a c e
> b d f
> 0 0 1

This is correct (it's just the transpose of the way I
wrote the matrix) but earlier you wrote the matrix as:
a b c
d e f
0 0 1

Which would not give you the right answer, I was
trying to help you out there (but I don't think it worked ;).

> Is their representation an AffineTransform or simply a matrix?

An AffineTransform is a matrix, so I'm not sure what
distinction you are trying to make.

> The next step is where I get a little lost.  We take three points
> that represent the unit box and "input" them?  Does this mean that
> we simply derive them from the matrix?  Or is this your
> demonstration of why this works and not part of the actual computation?

It's part of my demonstration (by input I meant transform the
points by the matrix).

> Point2D upperLeft = new Point2D.Double(0, 1);
> Point2D derivedUpperLeft = at.transform(upperLeft);
> derivedPoint.equals(new Point2D.Double(a, b));  // This should be true?

Actually I think it should be (c+e, d+f) assuming
a & b are meant to be from the constructor of the matrix.  Also
while (0, 1) would be upper left in a Cartesian coordinate
system it's bottom left in SVG (I'm not trying to nit pick
just want to make sure we are on the same page).

> So yes, given the src, you map to the common unit and from there you
> can map to the destination.  I think I follow that.  I guess the
> only confusion is why the matrix representation doesn't match what I
> normally expect.

I think it's the same (I always think of the matrix transposed,
so I probably confused you - sorry).

> From: thomas.deweese@kodak.com [mailto:thomas.deweese@kodak.com]
> Sent: Fri 10/3/2008 3:08 PM
> To: batik-users@xmlgraphics.apache.org
> Cc: batik-users@xmlgraphics.apache.org
> Subject: RE: Tracking changes to the rendering transform?
>
>
>
> Hi Michael,
>
> "Bishop, Michael W. CONTR J9C880" <michael.bishop.ctr@jfcom.mil>
> wrote on 10/03/2008 02:53:06 PM:
>
> > > parl_to_parl takes two double[] src and dst as arguments.  The
> > > method maps one parallelogram to another, but
> > > why does each double[] have 6 points?  What is being passed in
> > > here, a transform or a parallelogram?  The rest of
> > > the code makes sense.
> >
> > I might've answered my own question here by looking around for
> > examples of the "three point" method.  I forgot that each point has
> > two coordinates.  I believe that the double[] of src (and dst) are:
> >
> > { x1, y1, x2, y2, x3, y3 }
>
>    Correct.
>
> > which is mapped into an AffineTransform (at) as such:
> >
> > (x2 - x1) (y2 - y1) (x3 - x1)
> > (y3 - y1) (x1     ) (y1     )
> > 0         0         1
>
>    This isn't a proper representation of their matrix.
> They store it as:
>         sx, shy
>         shx, sy
>         tx , ty
>
>    So it's:
>         (x2 - x1) (y2 - y1)  0
>         (x3 - x1) (y3 - y1)  0
>         (x1     ) (y1     )  1
>
>   Now if you input the points (0,0), (1,0), (0,1)
> [the corners of a unit box] you get:
>
>         (x1, y1), ((x2-x1)+x1, (y2-y1)+y1), ((x3-x1)+x1, ((y3-y1)+y1))
> ->    (x1, y1), (x2, y2), (x3, y3)
>
>    The corners of your parallelogram; so that matrix maps
> the unit box to the parallogram.
>
>
> > What happens next is that "at" is inverted,
>
>    Which gives you the matrix from the parallelogram to
> the unit box.
>
> > then multiplied by a  similar transform derived from
> > the set of dst points.
>
>    So you have a matrix that goes src -> unit box -> dst.
>
> >  Now you have your new transform (D*).
> >
> > I have no idea WHY this works, but I think I'm on the right track of
> > HOW it works.
>
>     Hopefully you have some idea why it works now...
>
> > From: Bishop, Michael W. CONTR J9C880 [mailto:michael.bishop.ctr@jfcom.mil]
> > Sent: Fri 10/3/2008 1:31 PM
> > To: batik-users@xmlgraphics.apache.org
> > Subject: RE: Tracking changes to the rendering transform?
> >
> >
> > Hi Thomas,
> >
> > I'm following you most of the way with the basic concept.  There are
> > a couple things I'm confused about:
> >
> > parl_to_parl takes two double[] src and dst as arguments.  The
> > method maps one parallelogram to another, but why does each double[]
> > have 6 points?  What is being passed in here, a transform or a
> > parallelogram?  The rest of the code makes sense.
> >
> > You also say the approach is to build a matrix that maps a unit
> > square to the edges of a parallelogram.  What is a unit square?  A
> > square that encompasses the parallelogram, much like a traditional
> > bounding box?  I guess I'm still fuzzy on the overall concept.
> >
> > Good point that what the receiving client is getting is an
> > "absolute" representation.  It's not really a delta, it represents
> > the current state, replacing whatever was there before.  I wasn't
> > thinking about it that way.  Your explanation makes sense in the
> > equation, but getting D* (applying the 3pt method) is where I'm
> > lost.  My method handles scaling, but yours handles everything, if I
> > could figure out how to use it given three points.
> >
> > I'd be interested to see how this works and think it'd be useful.  I
> > made it through Ordinary Differential Equations in school, so I'm
> > happy to finally be putting Linear Algebra and Trig to use in my career.
> >
> > Michael
> >
> > ________________________________
> >
> > From: thomas.deweese@kodak.com [mailto:thomas.deweese@kodak.com]
> > Sent: Fri 10/3/2008 10:54 AM
> > To: batik-users@xmlgraphics.apache.org
> > Cc: batik-users@xmlgraphics.apache.org
> > Subject: RE: Tracking changes to the rendering transform?
> >
> >
> >
> > Hi Michael,
> >
> > "Bishop, Michael W. CONTR J9C880" <michael.bishop.ctr@jfcom.mil>
> > wrote on 10/03/2008 10:22:42 AM:
> >
> > > > Once the receiving client gets these three points, I'm not clear
> > > on how to derive the transform from the three
> > > > points.  That's a math issue, not a Batik issue of course.
> > >
> > > OK, I've been thinking about this issue some.  I think I have an
> > > idea for translate/scale, but I'm not sure about other transform values.
> >
> >    The best example I could find with google was the affine class from agg:
> >
> > https://svn.enthought.
> > com/enthought/browser/trunk/src/lib/enthought/kiva/agg/agg-2.
> > 4/src/agg_trans_affine.cpp?rev=7913
> >
> >
> >    It has parl_to_parl methods that map any parallelogram to another
> > parallelogram.
> >
> > > Let's say the receiving client receives 3 points; A1 (upper-left),
> > > A2 (upper-right), and A3 (lower-left).
> > > The receiving client already has a JSVGCanvas with three points
> C1, C2, C3.
> >
> >    The important thing about the three point approach is that you
> > honestly don't care what the destination canavas was showing, all
> > you want to do is map those three points to the corners of the
> > client's window (I would ignore aspect ratio issues to start with,
> > but the basic idea would be to modify the target canvas coordinates
> > to account for aspect ratio differences).
> >
> > > I'm thinking that a translation is derived to translate C1 to A1.
> > > Now both of the upper-left corners match.  Now for X scale, you
> > > calculate the distance between C1 and C2 and A1 and A2 and apply the
> > > right scale multiple  For Y, it's C1 and C3 and A1 and A3.
> >
> >    This is correct and will handle scaling but see the example
> > code as it will handle any rotation/skew as well.
> >
> > > I don't think you scale around the center; you scale around the
> > > origin (C1).
> >
> >    Correct.
> >
> > > What I'm not clear on now is the (unlikely) case of other transforms
> > > such as rotation, skew, and shear.
> >
> >    These should all just drop out of the above approach, that is what
> > is so nice about it.
> >
> > > Am I even on the right track for starting to handle these changes?
> >
> >    Yes, I think so, but trying to figure out how to derive the
> > affine to map any three src points to three dest points isn't
> > trivial unless you have a really good understanding of affine
> > transforms.  At some point I may try and write something for
> > the wiki that explains how that 3pt mapping code
> > works as it illustrates some useful ways of thinking about
> > affine transforms.
> >
> >    The basic approach is to build a matrix that maps a
> > unit square to the edges of any parallelogram.  Then you
> > can use inverse and multiply to map between parallelograms.
> >
> >
> > > From: Bishop, Michael W. CONTR J9C880 [mailto:michael.bishop.
> ctr@jfcom.mil]
> > > Sent: Thu 10/2/2008 11:04 AM
> > > To: batik-users@xmlgraphics.apache.org
> > > Subject: RE: Tracking changes to the rendering transform?
> >
> > > > You aren't done yet...
> > >
> > > This is where I start to get confused.  I have to remove the
> > > existing VIEWING transform to derive the RENDERING transform?  So I
> > > "remove" the VIEWING transform by doing the inverse, then apply that
> > > inverse to the RENDERING transform to get the final value?
> >
> >    Right it's useful to view it this way:
> >         D = Display transform, goes from Root SVG elements
> >             coordinate system to screen pixels.
> >         V = Viewing transform, the transform established by
> >             the viewBox and window size.
> >         R = Rendering transform, the transform created by pan/zoom/rotate.
> >
> >         V*R = D
> >
> >     Using the 3pt method you will calculate a new D -> D'.  So you
> >     want to calculate an R' such that:
> >         V*R' = D'
> >
> >     The easiest way to do that is:
> >         inv(V)*V*R' = inv(V)*D'
> >     Which is the same as:
> >         R' = inv(V)*D'
> >
> >
> >
> > >
> > > From: thomas.deweese@kodak.com [mailto:thomas.deweese@kodak.com]
> > > Sent: Tue 9/30/2008 9:21 PM
> > > To: batik-users@xmlgraphics.apache.org
> > > Cc: batik-users@xmlgraphics.apache.org
> > > Subject: RE: Tracking changes to the rendering transform?
> > >
> > >
> > >
> > > Hi Michael,
> > >
> > > "Bishop, Michael W. CONTR J9C880" <michael.bishop.ctr@jfcom.mil>
> > > wrote on 09/25/2008 01:13:47 PM:
> > >
> > > >    "The one thing you need to consider is that the rendering transform

> > > > does interact with the viewing transform (From the viewbox).  So in
> > > > the case that the window that is viewing the document is a different
> > > > size/aspect ratio then you may need a different rendering transform
> > > > to get the same 'view'. "
> > > >
> > > > In a whiteboarding situation, the document is supposed to stay in
> > > > sync between clients.  Assuming that we are syncing changes to the
> > > > viewBox attribute, does this satisfy the need to manage the
> > > viewing transform?
> > >
> > >    I don't think so...
> > >
> > >    Since the rendering transform sits outside of the viewing transform
> > > if one client has a window that is say 600 pixels wide and is paned over
> > > so that the left edge is in the middle of the screen their translate
> > > would be 300.   However if that is applied to a Window that is 1200
> > > pixels wide the left edge would only be 1/4 of the way across.
> > >
> > >    One way to view this problem is to communicate what points in
> > > the root SVG element's coordinate system correspond to the corners
> > > of the window.  With that in mind it's worth noting that a general
> > > affine transform can be specified by the remapping of three points
> > > (e.g. top left, top right, and bottom left points that are visible
> > > in the document).  So you can easily calculate those points by
> > > mapping the corners of the window to the root SVG element's coordinate
> > > system (on change of the rendering transform).  If you then send
> > > those points to the other clients they can calculate the transform
> > > that would map those same points to the corners of the new client's
> > > window (probably with some adjustment for aspect ratio - which is
> > > simple if you don't allow for non-uniform scaling).  You aren't
> > > done yet because that is the full transform and you need to remove
> > > the existing viewing transform to know what the rendering transform
> > > should be.  Fortunately that is simply a matter of inverting the
> > > viewing transform and multiplying/premultiplying that with the
> > > 'full transform' to get the residual that should be set as the
> > > rendering transform.
> > >
> > >    I hope that this makes some sense to you.
> > >
> > > > From: thomas.deweese@kodak.com [mailto:thomas.deweese@kodak.com]
> > > > Sent: Thu 9/25/2008 6:34 AM
> > > > To: batik-users@xmlgraphics.apache.org
> > > > Cc: batik-users@xmlgraphics.apache.org
> > > > Subject: RE: Tracking changes to the rendering transform?
> > > >
> > > >
> > > >
> > > >
> > > > Hi Dan,  Michael,
> > > >
> > > > "Dan Slater" <dslater@simulsoft.com> wrote on 09/23/2008 02:01:01
PM:
> > > >
> > > > > Extend the JSVGCanvas and override the setRenderingTransform method.
> > > > > For example:
> > > >
> > > >    Yes, this is how I would track changes to the rendering transform.

> > > > We don't expose it through any of the Swing change API's.
> > > >
> > > > >         public void setRenderingTransform(final AffineTransform at)
{
> > > > >             //System.out.println("JSVGCanvasX set rendering
> > > transform...");
> > > > >             setRenderingTransform(at, true);
> > > > >             Point2D.Double pt2d = new Point2D.
> > > > > Double(locationListener.getLastX(),locationListener.getLastY());
> > > > >             SVGSVGElement root = this.getSVGDocument().
> getRootElement();
> > > > >             if (root != null) setUserPositionXY(pt2d, root);
> > > > >        }
> > > >
> > > > "Bishop, Michael" <michael.bishop.ctr@jfcom.mil> wrote on 09/23/2008:
> > > >
> > > > >> I'm in a whiteboarding situation where I want to communicate
my
> > > > >> "view" to other users. If I pan/zoom/etc, I want to be able to

> > > > >> notify the other users as to what I'm looking at. I'm talking
> > > > >> view changes that do not modify the document.
> > > > >
> > > > >> I believe I can do this by tracking the render transform. Is
there a
> > > > >> way to listen for changes to the render transform?
> > > >
> > > >     See above...
> > > >
> > > > >> Is there anything else I have to think about tracking to achieve

> > > > >> this goal? I know the "viewBox" attribute exists, but that's

> > > > >> different; it's a modification to the document itself.
> > > >
> > > >    The one thing you need to consider is that the rendering transform

> > > > does interact with the viewing transform (From the viewbox).  So in
> > > > the case that the window that is viewing the document is a different
> > > > size/aspect ratio then you may need a different rendering transform
> > > > to get the same 'view'.
> > > >
> > > > [attachment "winmail.dat" deleted by Thomas E. DeWeese/449433/EKC]
> > > > ---------------------------------------------------------------------
> > > > To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
> > > > For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org
> > > [attachment "winmail.dat" deleted by Thomas E. DeWeese/449433/EKC]
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
> > > For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org
> > [attachment "winmail.dat" deleted by Thomas E. DeWeese/449433/EKC]
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
> > For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org
> [attachment "winmail.dat" deleted by Thomas E. DeWeese/449433/EKC]
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
> For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org

```
Mime
View raw message