Hi Michael,
"Bishop, Michael W. CONTR J9C880" <[EMAIL PROTECTED]> wrote on
10/06/2008 03:32:33 PM:
> I thought the difference between an AffineTransform and a matrix was
> that an AffineTransform was a specific 3x3 matrix used for
> translate, rotation, etc.
So an AffineTransform is a 3x3 matrix with a particular
'interpretation'
applied to it. All of the operations are really just straight matrix ops.
I don't think this is important now but I asked the question because you
seemed to be asking if the AGG implementation was missing(?) something.
> 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});
This all looks good to me.
> Point2D upperLeft = new Point2D.Double(0, 1);
> Point2D derivedUpperLeft = at.transform(upperLeft);
> derivedUpperLeft.equals(new Point2D.double(x1, y1)); // True?
No, derivedUpperLeft (I would call it lower left given
Java2D & SVG coordinate system have Y down) will equal x3, y3.
Let me summarize the mapping of points from the unit cube:
0,0 -> x1, y1 (upper left)
1,0 -> x2, y2 (upper right)
0,1 -> x3, y3 (lower left)
> 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.
I think you are confused when you say 0,1 is the upper left corner,
0,0 is the upper left and will map to x1,y1.
> 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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
> Sent: Fri 10/3/2008 5:05 PM
> To: [email protected]
> Cc: [email protected]
> Subject: RE: Tracking changes to the rendering transform?
>
>
>
> Hi Michael,
>
> "Bishop, Michael W. CONTR J9C880" <[EMAIL PROTECTED]>
> 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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
> > Sent: Fri 10/3/2008 3:08 PM
> > To: [email protected]
> > Cc: [email protected]
> > Subject: RE: Tracking changes to the rendering transform?
> >
> >
> >
> > Hi Michael,
> >
> > "Bishop, Michael W. CONTR J9C880" <[EMAIL PROTECTED]>
> > 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.
> [EMAIL PROTECTED]
> > > Sent: Fri 10/3/2008 1:31 PM
> > > To: [email protected]
> > > 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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
> > > Sent: Fri 10/3/2008 10:54 AM
> > > To: [email protected]
> > > Cc: [email protected]
> > > Subject: RE: Tracking changes to the rendering transform?
> > >
> > >
> > >
> > > Hi Michael,
> > >
> > > "Bishop, Michael W. CONTR J9C880" <[EMAIL PROTECTED]>
> > > 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.
> > [EMAIL PROTECTED]
> > > > Sent: Thu 10/2/2008 11:04 AM
> > > > To: [email protected]
> > > > 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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
> > > > Sent: Tue 9/30/2008 9:21 PM
> > > > To: [email protected]
> > > > Cc: [email protected]
> > > > Subject: RE: Tracking changes to the rendering transform?
> > > >
> > > >
> > > >
> > > > Hi Michael,
> > > >
> > > > "Bishop, Michael W. CONTR J9C880" <[EMAIL PROTECTED]>
> > > > wrote on 09/25/2008 01:13:47 PM:
> > > >
> > > > > "The one thing you need to consider is that the
renderingtransform
> > > > > 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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
> > > > > Sent: Thu 9/25/2008 6:34 AM
> > > > > To: [email protected]
> > > > > Cc: [email protected]
> > > > > Subject: RE: Tracking changes to the rendering transform?
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > Hi Dan, Michael,
> > > > >
> > > > > "Dan Slater" <[EMAIL PROTECTED]> 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" <[EMAIL PROTECTED]> 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 about
> > > > > >> 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:
[EMAIL PROTECTED]
> > > > > For additional commands, e-mail: batik-users-
> [EMAIL PROTECTED]
> > > > [attachment "winmail.dat" deleted by Thomas E. DeWeese/449433/EKC]
> > > >
---------------------------------------------------------------------
> > > > To unsubscribe, e-mail:
[EMAIL PROTECTED]
> > > > For additional commands, e-mail:
[EMAIL PROTECTED]
> > > [attachment "winmail.dat" deleted by Thomas E. DeWeese/449433/EKC]
> > >
---------------------------------------------------------------------
> > > To unsubscribe, e-mail:
[EMAIL PROTECTED]
> > > For additional commands, e-mail:
[EMAIL PROTECTED]
> > [attachment "winmail.dat" deleted by Thomas E. DeWeese/449433/EKC]
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail:
[EMAIL PROTECTED]
> [attachment "winmail.dat" deleted by Thomas E. DeWeese/449433/EKC]
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]