﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-温馨小小窝-随笔分类-转载文字</title><link>http://www.cnitblog.com/wjh1025/category/1834.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 30 Sep 2011 15:34:46 GMT</lastBuildDate><pubDate>Fri, 30 Sep 2011 15:34:46 GMT</pubDate><ttl>60</ttl><item><title>SVG主要元素和属性</title><link>http://www.cnitblog.com/wjh1025/archive/2006/01/12/6152.html</link><dc:creator>WJH</dc:creator><author>WJH</author><pubDate>Thu, 12 Jan 2006 13:16:00 GMT</pubDate><guid>http://www.cnitblog.com/wjh1025/archive/2006/01/12/6152.html</guid><wfw:comment>http://www.cnitblog.com/wjh1025/comments/6152.html</wfw:comment><comments>http://www.cnitblog.com/wjh1025/archive/2006/01/12/6152.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/wjh1025/comments/commentRss/6152.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/wjh1025/services/trackbacks/6152.html</trackback:ping><description><![CDATA[<P align=left><IMG alt="" src="http://bbs.xml.org.cn/face/face1.gif" border=0 dypop="发贴心情">&nbsp;<B>SVG主要元素和属性</B><BR></P>
<DIV align=left width="100%">
<DIV style="FLOAT: right"></DIV></DIV>
<DIV align=left width="100%">SVG主要元素和属性<BR>&lt;desc&gt;&lt;/desc&gt;&nbsp;&nbsp;注释&lt;!--&nbsp;--&gt;</DIV>
<P align=left width="100%">&lt;defs&gt;&lt;/defs&gt;&nbsp;&nbsp;预定义&nbsp;待引用&nbsp;&nbsp;&lt;element&nbsp;id="name"&gt;&nbsp;&nbsp;引用属性：url(#name)</P>
<P align=left width="100%">&lt;use&nbsp;xlink:href&gt;&lt;/use&gt;&nbsp;&nbsp;&nbsp;&nbsp;引用元素&nbsp;</P>
<P align=left width="100%">&lt;symbol&gt;&nbsp;&nbsp;模版</P>
<P align=left width="100%">&lt;image&nbsp;width&nbsp;height&gt;&nbsp;width&nbsp;height不能省</P>
<P align=left width="100%">属性&nbsp;xml:space="default|preserve"&nbsp;英文空格</P>
<P align=left width="100%">属性&nbsp;externalResourceRequired="false|true"&nbsp;&nbsp;必需外部资源与否&nbsp;&nbsp;若为true&nbsp;找不到外部资源&nbsp;&nbsp;<BR>不支持&lt;switch&gt;&lt;&gt;选择&nbsp;平台</P>
<P align=left width="100%">&lt;rect&nbsp;x&nbsp;y&nbsp;width&nbsp;height&nbsp;rx&nbsp;ry&gt;&nbsp;&nbsp;rx&nbsp;ry椭圆半径<BR>&nbsp;&nbsp;&nbsp;&nbsp;圆角矩形的圆角过渡部分是一段四分之一的椭圆弧，&nbsp;&nbsp;分别代表其半<BR>长轴和半短轴。当只指明了“rx”或“ry”其中的一个时，另一个缺省值与这个相等。<BR>如果都不指定，则缺省值为o，此时矩形的4个角为直角。如果“rx”的值大于矩形宽<BR>度的一半，则作为一半处理。</P>
<P align=left width="100%">&lt;circle&nbsp;cx&nbsp;cy&nbsp;r&nbsp;&gt;</P>
<P align=left width="100%">&lt;ellipse&nbsp;cx&nbsp;cy&nbsp;rx&nbsp;ry&gt;</P>
<P align=left width="100%">&lt;line&nbsp;x1&nbsp;y1&nbsp;x2&nbsp;y2&gt;</P>
<P align=left width="100%">&lt;polyline&nbsp;points="x0,y0&nbsp;x1,y1&nbsp;&nbsp;......"&gt;&nbsp;折线</P>
<P align=left width="100%">&lt;polygon&nbsp;points="x0,y0&nbsp;x1,y1&nbsp;&nbsp;......"&gt;&nbsp;多边形</P>
<P align=left width="100%">&lt;path&nbsp;d="M|L|C|S|Q|T|A|Z"&nbsp;length=&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;(])所有的绘图指令都只用一个字母来表示。<BR>&nbsp;&nbsp;&nbsp;&nbsp;(2)坐标数据和指令之间的空格可以省略，但坐标致据之间的空格显然不能省略。<BR>&nbsp;&nbsp;&nbsp;&nbsp;(3)问一行中出现问一条命令多次连续重复使用的情况时，命令名可以只使用第一个，<BR>后面的省略，不过用于数据分网的空格同样不能少。<BR>&nbsp;&nbsp;&nbsp;&nbsp;(4)命令名是大写字母时代表后面所跟的数据值是绝对坐标，小写字母代表相对坐标。<BR>&nbsp;&nbsp;&nbsp;&nbsp;(5)当绘制水平或垂直线段时，可以使用H和V命令代替L。使用H或h时，后面只需要<BR>加一个代表x坐标的参数，Y坐标映省与当前点相同。同样，使用v或v时，后面也只需<BR>要加一个代表Y坐标的参数。如果这两个命令字母后面跟了多个数值,则每一个数值被<BR>认为是一次单独的绘制线条的命令，而不像L和1命令那样把每两个数值结合起来作为<BR>一个点的一对坐标值来加以处理。<BR>&nbsp;&nbsp;&nbsp;&nbsp;(6)一对坐标值的XY坐标之间可以用空格或逗号隔开，但坐标对与坐标对之间只能<BR>用空格作为分隔符。<BR>&nbsp;&nbsp;&nbsp;&nbsp;(7)路径闭合命令虽然也有Z和z：两种形式，可效果是一样的，使用时没有区别。<BR>本命令不带参数，功能也比较简单，直接从当前点绘制一条直线到本条子路径的起点。<BR>&nbsp;&nbsp;&nbsp;&nbsp;(8)s和s命令是绘制“光滑”三次贝塞尔曲线的命令。一条复杂的曲线由多个曲线弧段<BR>所构成，弧段与弧段之间要光滑衔接，各个弧段的控制点必须满足一定条件。首先，这一<BR>段曲线弧的起点必须是前一段曲线弧的终点，否则连不上；其次，这一段曲线弧的第一控<BR>制点必须与前一段曲线弧的第二控制点呈对称关系，对称中心是这段曲线弧的起点，只有<BR>这样才能保证曲线衔接处的光滑。S和s命令的语法是“S&nbsp;X2&nbsp;y2&nbsp;destx&nbsp;desty”，省略了光滑<BR>曲线弧所隐含的第一个控制点的坐标。命令执行完后，当前点坐标同样停留在最后绘制的<BR>一段曲线弧的终点上。</P>
<P align=left width="100%">椭圆弧曲线命令用A或a来表示。其语法比较复杂，是"A&nbsp;rx&nbsp;ry&nbsp;x-axis-rotation&nbsp;large-arc-flag&nbsp;<BR>sweep-flag&nbsp;x&nbsp;y"&nbsp;&nbsp;"x-axis-rotation"是此段弧所在的椭圆的X轴与水平方向的夹角，也即x轴的<BR>旋转角度;large-arc-flag、sweep-flag决定了椭圆弧的绘制方向，值是0或1；(x，y)是椭圆弧<BR>终点坐标。至于圆心坐标则是自动计算出来的。</P>
<P align=left width="100%">viewBox属性&nbsp;not&nbsp;viewbox&nbsp;&nbsp;缺省单位度量</P>
<P align=left width="100%">transform属性&nbsp;="translate|rotate|skewX|skewY|scale|matrix(a&nbsp;b&nbsp;c&nbsp;d&nbsp;e&nbsp;f)"</P>
<P align=left width="100%">preserveAspectRatio属性</P>
<P align=left width="100%">&lt;text&nbsp;x&nbsp;y&nbsp;textLength&nbsp;lengthAdjust&gt;</P>
<P align=left width="100%">&lt;tspan&nbsp;x&nbsp;y&nbsp;dx&nbsp;dy&nbsp;rotate&gt;从属于&lt;text&gt;<BR>&lt;svg&gt;<BR>&nbsp;&nbsp;&lt;text&nbsp;style="fill:#000000;font-family:Arial;font-weight:bold;font-size:40;"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;tspan&nbsp;x="50"&nbsp;y="60,70,80,80,75,60,80,70"&gt;COMMUNICATION&lt;/tspan&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;tspan&nbsp;x="50"&nbsp;y="150"&nbsp;dx="0,15"&nbsp;dy="10,10,10,-10,-10,-10,10,10,-10"&gt;COMMUNICATION&lt;/tspan&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;tspan&nbsp;x="50"&nbsp;y="230"&nbsp;rotate="10,20,30,40,50,60,70,80,90,90,90,90,90"&gt;COMMUNICATION&lt;/tspan&gt;<BR>&nbsp;&nbsp;&lt;/text&gt;<BR>&lt;/svg&gt;</P>
<P align=left width="100%">&lt;tref&nbsp;xlink:href="#"&gt;引用&lt;defs&gt;中的&lt;text&gt;</P>
<P align=left width="100%">&lt;glyphRun&gt;</P>
<P align=left width="100%">&lt;altGlyph&nbsp;xlink:href="#id"&gt;</P>
<P align=left width="100%">&lt;altGlyphDef&nbsp;id=""&gt;</P>
<P align=left width="100%">&lt;glyphRef&nbsp;xlink:href=&nbsp;glyphRef=&gt;</P>
<P align=left width="100%">&lt;textPath&nbsp;startOffset=&nbsp;method="align|stretch"&nbsp;spacing="exact|auto"&nbsp;xlink:href=""&gt;注意嵌套的&lt;tspan&gt;对<BR>后面的走向有叠加作用</P>
<P align=left width="100%">fill-rule属性&nbsp;fill-rule="nonezero|evenodd"</P>
<P align=left width="100%">fill-opacity属性&nbsp;fill-opacity="1|0~1"&nbsp;&nbsp;</P>
<P align=left width="100%">stroke-opacity&nbsp;属性</P>
<P align=left width="100%">stroke-linecap=butt|round|square</P>
<P align=left width="100%">stroke-linejoin=miter|round|bevel|</P>
<P align=left width="100%">stroke-dasharray="length&nbsp;spacing"</P>
<P align=left width="100%">stroke-dashoffset="0|"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;表示描边时使用描边模板(如线型、渐变色彩等)的起始偏移量，<BR>缺省值是0，即从头开始。</P>
<P align=left width="100%">&lt;maker&nbsp;makerWidth&nbsp;makerHeight&nbsp;makerUnits&nbsp;refX&nbsp;refY&nbsp;orient&gt;</P>
<P align=left width="100%">marker-start:url(#)&nbsp;marker-mid:url(#)&nbsp;&nbsp;marker-end:url(#)</P>
<P align=left width="100%">color-interpolation="auto|sRGB|linearRGB"</P>
<P align=left width="100%">color-rendering="auto|optimizeSpeed|optimizeQuality"</P>
<P align=left width="100%">shape-rendering="auto|optimizeSpeed|crispEdges|geometricPrecision"</P>
<P align=left width="100%">text-rendering="auto|optimizeSpeed|optimizeLegibility|geometricPrecision"</P>
<P align=left width="100%">image-rendering="auto|optimizeSpeed|optimizeQuality"</P>
<P align=left width="100%">&lt;a&nbsp;xlink:href=&nbsp;xlink:type="simple"&nbsp;xlink:show="new|replace"&nbsp;xlink:title&nbsp;xlink:actuate="onRequest"&nbsp;<BR>target="_top|_self"&gt;</P>
<P align=left width="100%">&lt;?xml-stylesheet&nbsp;href=".css"&nbsp;type="text/css"?&gt;</P>
<P align=left width="100%">&lt;style&nbsp;type="text/css|text/xsl"&nbsp;media="screen|print"&gt;&lt;!CDATA[]&gt;&nbsp;&lt;/style&gt;</P>
<P align=left width="100%">&lt;linearGradient&nbsp;id&nbsp;x1&nbsp;y1&nbsp;x2&nbsp;y2&nbsp;gradientUnits="objectBoundingBox|userSpaceOnUse"&nbsp;<BR>spreadMethod="pad|reflect|repeat"&nbsp;xlink:href=""&nbsp;gradientTransform=""&gt;&nbsp;&nbsp;<BR>事实证明缺省时即gradientUnits="objectBoundingBox"时x&nbsp;1&nbsp;y1&nbsp;等属性不起作用</P>
<P align=left width="100%">&lt;radialGradient&nbsp;id&nbsp;cx&nbsp;cy&nbsp;r&nbsp;fx&nbsp;fy&nbsp;gradientUnits="objectBoundingBox|userSpaceOnUse"&nbsp;<BR>spreadMethod="pad|reflect|repeat"&nbsp;&nbsp;xlink:href=""&nbsp;gradientTransform=""&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;cx&nbsp;cy是形状圆心&nbsp;&nbsp;fx&nbsp;fy是色彩中心</P>
<P align=left width="100%">&lt;stop&nbsp;offset="&lt;length&gt;"&nbsp;stop-color=""&nbsp;stop-opacity=""&nbsp;&gt;</P>
<P align=left width="100%">&lt;pattern&nbsp;id&nbsp;x&nbsp;y&nbsp;width&nbsp;height&nbsp;patternUnits="objectBoundingBox|userSpaceOnUse"&nbsp;<BR>viewBox=""&nbsp;patternTransform&nbsp;xlink:href=""&nbsp;patternTransform=""&gt;</P>
<P align=left width="100%">overflow="visible|hidden|scroll|auto"</P>
<P align=left width="100%">clip="rect(x1&nbsp;y1&nbsp;x2&nbsp;y2)|auto"</P>
<P align=left width="100%">&lt;clipPath&nbsp;id&nbsp;clipPathUnits="objectBoundingBox|userSpaceOnUse"&nbsp;clip-Path="url"&nbsp;<BR>clip-rule="nonezero|evenodd"&gt;还可以使用文字作为剪裁路径，此时的“c加·mle”<BR>参数大多数情况都应该设置为“evenodd”，因为文字的轮廓通常都是交叉的。</P>
<P align=left width="100%">&lt;mask&nbsp;id&nbsp;maskUnits="objectBoundingBox|userSpaceOnUse"&nbsp;x=&nbsp;y=&nbsp;width&nbsp;height&nbsp;mask="url()"&gt;</P>
<P align=left width="100%">opacity=&nbsp;&nbsp;具有继承性和迭加性</P><img src ="http://www.cnitblog.com/wjh1025/aggbug/6152.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/wjh1025/" target="_blank">WJH</a> 2006-01-12 21:16 <a href="http://www.cnitblog.com/wjh1025/archive/2006/01/12/6152.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于Batik的SVG应用: 关于几何变换[转帖]</title><link>http://www.cnitblog.com/wjh1025/archive/2006/01/07/6074.html</link><dc:creator>WJH</dc:creator><author>WJH</author><pubDate>Sat, 07 Jan 2006 11:14:00 GMT</pubDate><guid>http://www.cnitblog.com/wjh1025/archive/2006/01/07/6074.html</guid><wfw:comment>http://www.cnitblog.com/wjh1025/comments/6074.html</wfw:comment><comments>http://www.cnitblog.com/wjh1025/archive/2006/01/07/6074.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/wjh1025/comments/commentRss/6074.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/wjh1025/services/trackbacks/6074.html</trackback:ping><description><![CDATA[<STRONG>基于Batik的SVG应用:&nbsp;关于几何变换[转帖]<BR></STRONG>
<DIV width="100%">
<DIV style="FLOAT: right"><STRONG></STRONG></DIV>
<DIV>SVG&nbsp;是一种用&nbsp;xml&nbsp;语言来描述二维图形对象的语言，SVG&nbsp;允许三种图形对象：1．矢量图形，2．图片，3．文本对象。这三种图形对象都可以支持分组，使用样式渲染，进行几何变换。 
<P></P>
<P>SVG&nbsp;还能够通过脚本来实现交互操作和动态显示。可以通过定义动画对象或使用script&nbsp;脚本来实现动画。</P>
<P>1.&nbsp;SVG&nbsp;下几种常见的几何变换方式</P>
<P><BR>1.1&nbsp;一个&nbsp;SVG&nbsp;例子<BR>我们首先来看一个&nbsp;SVG&nbsp;的例子，窗口右上角有四个色块，每个色块是一个50×50的矩形。</P>
<P>图&nbsp;1.&nbsp;一个&nbsp;SVG&nbsp;的样本<BR>&nbsp;</P>
<P>图&nbsp;2.&nbsp;样本文档</P>
<P>&lt;?xml&nbsp;version="1.0"?&gt;<BR>&lt;svg&nbsp;&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;g&gt;&nbsp;<BR>&nbsp;&lt;rect&nbsp;x="0"&nbsp;y="0"&nbsp;width="50"&nbsp;height="50"&nbsp;style="fill:red"&nbsp;/&gt;<BR>&nbsp;&lt;rect&nbsp;x="50"&nbsp;y="0"&nbsp;width="50"&nbsp;height="50"&nbsp;style="fill:yellow"&nbsp;/&gt;<BR>&nbsp;&lt;rect&nbsp;x="0"&nbsp;y="50"&nbsp;width="50"&nbsp;height="50"&nbsp;style="fill:green"&nbsp;/&gt;<BR>&nbsp;&lt;rect&nbsp;x="50"&nbsp;y="50"&nbsp;width="50"&nbsp;height="50"&nbsp;style="fill:black"&nbsp;/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/g&gt;<BR>&lt;/svg&gt;</P>
<P>&nbsp;</P>
<P>1.2&nbsp;使用&nbsp;Adobe&nbsp;SVG&nbsp;Viewer&nbsp;展示在&nbsp;SVG&nbsp;文档中实现的几何变换<BR>缩放&lt;g&nbsp;transform="scale(2)"&gt;</P>
<P>图&nbsp;3.&nbsp;放大一倍<BR>&nbsp;</P>
<P>平移&lt;g&nbsp;transform="translate(200&nbsp;,200)"&gt;</P>
<P>图&nbsp;4.&nbsp;平移200，200个像素<BR>&nbsp;</P>
<P>旋转&lt;g&nbsp;transform="rotate(45)"&gt;</P>
<P>图&nbsp;5.&nbsp;顺时针旋转45度<BR>&nbsp;</P>
<P>横切&lt;g&nbsp;transform="skewX(45)"&gt;</P>
<P>图&nbsp;6.&nbsp;以&nbsp;y&nbsp;轴为基线在&nbsp;X&nbsp;方向横切45度<BR>&nbsp;</P>
<P>2.&nbsp;在&nbsp;Batik&nbsp;下实现&nbsp;SVG&nbsp;的几何变换</P>
<P><BR>2.1&nbsp;Batik&nbsp;的基础知识<BR>2.1.1&nbsp;Batik&nbsp;的用途&nbsp;</P>
<P>Batik&nbsp;是基于&nbsp;java&nbsp;语言实现的一个&nbsp;SVG&nbsp;应用的工具集，用于实现对&nbsp;SVG&nbsp;对象的显示、编辑以及将&nbsp;SVG&nbsp;图形对象转换成其他图片格式，如&nbsp;jpg、gif&nbsp;等。</P>
<P>这个项目的目标就是给开发人员一套用于处理或应用&nbsp;SVG&nbsp;对象的基础核心模型。作为Apache&nbsp;项目成员之一，该项目也为开发人员提供了一个开发的可扩展的平台。同时&nbsp;batik&nbsp;也维护了一个可以查看&nbsp;SVG&nbsp;文件的浏览器。虽然&nbsp;batik&nbsp;还没有完全实现&nbsp;SVG&nbsp;的所有标准语法和标记，但通过比较不同版本的区别就会发现，他正在以很高的效率覆盖&nbsp;SVG&nbsp;所有的标准。</P>
<P>2.1.2&nbsp;让我们实现一个简单的&nbsp;Batik&nbsp;程序&nbsp;</P>
<P>首先让我们实现一个简单的基于&nbsp;Batik&nbsp;的&nbsp;SVG&nbsp;浏览器。Batik&nbsp;封装了org.apache.batik.swing.JSVGCanvas&nbsp;对象可以用于在&nbsp;swing&nbsp;中嵌入&nbsp;SVG&nbsp;显示容器，并可以通过&nbsp;org.apache.batik.swing.JSVGCanvas&nbsp;提供的方法对&nbsp;SVG&nbsp;文档和图像进行操作。这个浏览器可以支持大部分&nbsp;SVG&nbsp;的语法和标准包括脚本交互的功能，但暂时还没有引入动画。关于动画和脚本交互的内容我们会在以后的文章中讲述，今天先集中解决几何变换的问题。</P>
<P>图&nbsp;7.&nbsp;运行程序打开我们编写的&nbsp;SVG&nbsp;的例子<BR>&nbsp;</P>
<P>可以通过该页面引导运行该程序：&nbsp;<BR>从附件中可以查看该程序的完整代码，也可通过&nbsp;网上下载地址&nbsp;运行该程序。&nbsp;</P>
<P>图&nbsp;8.&nbsp;将一个&nbsp;SVGCanvas&nbsp;添加到界面</P>
<P>private&nbsp;javax.swing.JPanel&nbsp;SVGPanel&nbsp;=&nbsp;new&nbsp;javax.swing.JPanel();<BR>private&nbsp;JSVGCanvas&nbsp;svgCanvas&nbsp;=&nbsp;new&nbsp;org.apache.batik.swing.JSVGCanvas();<BR>SVGPanel.add("Center",&nbsp;svgCanvas);</P>
<P>&nbsp;</P>
<P>2.2&nbsp;通过&nbsp;Batik&nbsp;的&nbsp;GVT&nbsp;模型实现&nbsp;SVG&nbsp;的几何变换<BR>2.2.1&nbsp;为什么要使用&nbsp;Batik&nbsp;来实现&nbsp;SVG&nbsp;的几何变换&nbsp;</P>
<P>当我们用&nbsp;Batik&nbsp;工具集作为&nbsp;SVG&nbsp;客户端的解决方案时，如缩放平移这样的操作就在所难免了。但&nbsp;Batik&nbsp;并没有直接支持如&nbsp;Adobe&nbsp;SVG&nbsp;Viewer&nbsp;那样的鼠标拖动几何变换的操作，这就要求我们对这些功能进行编程处理。</P>
<P>在分析&nbsp;SVG&nbsp;的几何变换的细节之前，先让我们了解一下基本的操作编程方式。</P>
<P>2.2.2&nbsp;Batik&nbsp;下通过&nbsp;java.awt.geom.AffineTransform&nbsp;来实现&nbsp;SVG&nbsp;的几何变换&nbsp;</P>
<P>JSVGCanvas&nbsp;提供方法可以获取&nbsp;java.awt.geom.AffineTransform&nbsp;对象。AffineTransform&nbsp;是用于实现2D&nbsp;几何图形坐标变换处理的对象，可以通过该对象进行二维几何空间中两个坐标系的相互映射和变换。</P>
<P>平移:</P>
<P></P>
<P>//向左和向下平移50个像素<BR>java.awt.geom.AffineTransform&nbsp;&nbsp;rat&nbsp;=&nbsp;svgCanvas.getRenderingTransform();<BR>rat.translate(50,50);<BR>svgCanvas.setRenderingTransform(rat);</P>
<P>&nbsp;</P>
<P>缩放:</P>
<P></P>
<P>//以屏幕左上角原点为固定点进行缩放操作<BR>java.awt.geom.AffineTransform&nbsp;&nbsp;rat&nbsp;=&nbsp;svgCanvas.getRenderingTransform();<BR>rat.scale(0.5,0.5);<BR>svgCanvas.setRenderingTransform(rat);</P>
<P>&nbsp;</P>
<P>旋转:</P>
<P></P>
<P>//以屏幕左上角原点为固定点进行旋转缩放<BR>java.awt.geom.AffineTransform&nbsp;&nbsp;rat&nbsp;=&nbsp;svgCanvas.getRenderingTransform();<BR>rat.rotate(3.1415926/4);<BR>svgCanvas.setRenderingTransform(rat);</P>
<P>&nbsp;</P>
<P>复合变换:</P>
<P></P>
<P>//一个综合平移、放大和旋转90度的复合变换<BR>java.awt.geom.AffineTransform&nbsp;&nbsp;rat&nbsp;=&nbsp;svgCanvas.getRenderingTransform();<BR>rat.translate(50，50);<BR>rat.scale(2，2);<BR>rat.rotate(3.1415926/4);<BR>svgCanvas.setRenderingTransform(rat);</P>
<P>&nbsp;</P>
<P>3.&nbsp;当我们需要进行复合几何变换的时候</P>
<P><BR>3.1&nbsp;先来让我们通过不同的变换代码组合实现复合几何变换<BR>先让我们看第一个例子:</P>
<P>//放大一倍和平移50个像素的复合变换&nbsp;</P>
<P>AffineTransform&nbsp;rat&nbsp;=&nbsp;svgCanvas.getRenderingTransform();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rat.scale(2,2);<BR>rat.translate(50,50);<BR>svgCanvas.setRenderingTransform(rat);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;</P>
<P>图&nbsp;9.&nbsp;复合变换一<BR>&nbsp;</P>
<P>可以看得出来，这个变换的最终效果是：图形的形状放大一倍，原图形的（0，0）原点坐标平移100个像素。</P>
<P>再来看第二个例子:</P>
<P></P>
<P>//放大一倍和平移50个像素的复合变换<BR>AffineTransform&nbsp;rat&nbsp;=&nbsp;svgCanvas.getRenderingTransform();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rat.translate(50,50);<BR>rat.scale(2,2);<BR>svgCanvas.setRenderingTransform(rat);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;</P>
<P>图&nbsp;10.&nbsp;复合变换二<BR>&nbsp;</P>
<P>这个变换的最终效果是：图形的形状放大一倍，原图形的（0，0）原点坐标平移50个像素。</P>
<P>3.2&nbsp;关键是顺序<BR>比较一下这两种平移后的效果会发现,只是因为缩放和平移的顺序不同，变换后的结果就发生了区别。第一个例子实际平移的不是50个像素,而是100个像素。而第二个例子则是平移了50个像素。</P>
<P>有兴趣的读者可以添加其他几何变换方式，并测试不同的变换顺序，会发现复合变换的顺序与复合变换的最终效果是紧密相关的。那么如何分析和计算复合变换的变换结果呢？这里我们需要补充一点数学知识了。</P>
<P>3.3&nbsp;对单一的几何变换进行数学模型分析<BR>对计算机图形学中图形变换相关理论很熟悉的人可以跳过这部分直接看&nbsp;Batik&nbsp;的实现方式。这节使用的齐次式图片引用自&nbsp;SVG标准中关于坐标变换的齐次式的例子插图。&nbsp;</P>
<P>首先我们来了解一下图形变换的齐次式计算方法：</P>
<P>图&nbsp;11.&nbsp;基本几何&nbsp;变换齐次式<BR>&nbsp;</P>
<P>这是一个基本图形变换齐次式。等式的最右边是一个坐标点未变换前的坐标矩阵，最左边是该坐标点变换后所在位置的一个三行一列的坐标矩阵，中间那个三行三列的矩阵就是变换矩阵。不同的变换方式将对应不同的变换矩阵，图形平移效果就是通过这样一个变换齐次式来实现的。</P>
<P>平移:如果需要将图形平移（tx，ty）个坐标时，采用如下的变换矩阵带入变换方程。</P>
<P>图&nbsp;12.&nbsp;平移变换矩阵<BR>&nbsp;</P>
<P>缩放：如果需要在&nbsp;x&nbsp;轴方向实现&nbsp;sx&nbsp;倍缩放，在&nbsp;y&nbsp;轴方向实现&nbsp;sy&nbsp;轴缩放时，采用如下的变换矩阵带入变换方程。</P>
<P>图&nbsp;13.&nbsp;缩放变换矩阵<BR>&nbsp;</P>
<P>旋转:如果需要将图像旋转&nbsp;a&nbsp;度时，使用如下的变换矩阵带入变换方程。</P>
<P>图&nbsp;14.&nbsp;旋转变换矩阵<BR>&nbsp;</P>
<P>3.4&nbsp;采用复合几何变换的数学模型分析<BR>3.4.1&nbsp;数学分析</P>
<P>当两组变换同时作用于同一个图像时，连续使用该等式，得出如下等式。由于做变换的时候是将变换矩阵放在矩阵积的左边，所以对于复合变换的式子，应该从右向左进行读。对于如下的式子：从右至左依次是变换前的坐标，第一次转换的转换矩阵，第二次转换的转换矩阵，转换后的坐标值。</P>
<P>图&nbsp;15.&nbsp;进行两次变换的复合矩阵<BR>&nbsp;</P>
<P>进一步推导&nbsp;n&nbsp;次几何变换的复合变换等式：</P>
<P>图&nbsp;16.&nbsp;n次变换的复合矩阵<BR>&nbsp;</P>
<P>3.4.2&nbsp;来实践一下&nbsp;</P>
<P>图&nbsp;17.&nbsp;变换前效果<BR>&nbsp;</P>
<P>使用这样一个复合变换方式：</P>
<P>&lt;g&nbsp;transform="translate(50,90)&nbsp;rotate(-45)&nbsp;translate(130,160)"&gt;&nbsp;</P>
<P>根据前面的分析结果带入变换方程，得出如下等式</P>
<P>图&nbsp;18.&nbsp;推导矩阵<BR>&nbsp;</P>
<P>根据计算后的变换矩阵，可得变换结果是图形整体平移到（255.03,111.21），同时图形自身沿顺时针方向旋转45度。查看实际变换结果，这里我们可以发现，对于&nbsp;SVG&nbsp;的变换来说，虽然我们习惯上从左往右写变换参数的，实际上图形做变换的时候是从右边的变换参数开始依次进行图形变换的。</P>
<P>图&nbsp;19.&nbsp;变换后效果<BR>&nbsp;</P>
<P>3.5&nbsp;分析一下&nbsp;Batik&nbsp;是如何实现&nbsp;SVG&nbsp;的复合几何变换的<BR>3.5.1&nbsp;先看第一个例子：&nbsp;</P>
<P>这个变换是先放大后平移的变换，其变换效果最终是，先将图形的形状放大一倍，然后将图形整个平移100个像素。这里我们可以看出，虽然我们是先进行的放大变换，后进行的平移操作，但当我们进行复合变换的时候由于实际运算时上是先进行了平移，后进行了缩放。或者简单的理解为从左向右先写缩放矩阵，再写平移矩阵，这样得出的变换矩阵就可以对变换后的效果进行计算了。</P>
<P></P>
<P>//放大一倍和平移50个像素的复合变换<BR>//&lt;g&nbsp;transform="&nbsp;scale(2&nbsp;)&nbsp;translate(50&nbsp;50)"&gt;<BR>AffineTransform&nbsp;rat&nbsp;=&nbsp;svgCanvas.getRenderingTransform();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rat.scale(2,2);<BR>rat.translate(50,50);<BR>svgCanvas.setRenderingTransform(rat);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;</P>
<P>我们可以将这个变换对应的计算矩阵写出来：</P>
<P>图&nbsp;20.&nbsp;复合变换例一的变换矩阵<BR>&nbsp;</P>
<P>根据上面的分析我们可以看的出，先进行缩放变换在进行平移变换的复合变换时，变换后原图元的坐标会映射到新的位置，其中：</P>
<P>X1=Sx(X+dx)&nbsp;<BR>Y1=Sy(Y+dy)&nbsp;</P>
<P>3.5.2&nbsp;再来看第二个例子：&nbsp;</P>
<P>这个变换是先放大后平移的变换，其变换效果最终是，先将图形整个平移50个像素，然后将图形的形状放大一倍。</P>
<P></P>
<P>//放大一倍和平移50个像素的复合变换<BR>//&lt;g&nbsp;transform="translate(50，50)&nbsp;scale(2&nbsp;)"&gt;<BR>AffineTransform&nbsp;rat&nbsp;=&nbsp;svgCanvas.getRenderingTransform();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rat.translate(50,50);<BR>rat.scale(2,2);<BR>svgCanvas.setRenderingTransform(rat);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;</P>
<P>我们可以将这个变换对应的&nbsp;svg&nbsp;文档实现写出来：</P>
<P>&lt;g&nbsp;transform="translate(50&nbsp;50)&nbsp;scale(2&nbsp;)"&gt;</P>
<P>图&nbsp;21.&nbsp;复合变换例二的变换矩阵<BR>&nbsp;</P>
<P>根据上面的分析我们可以看的出，先进行平移变换再进行缩放变换的复合变换时，变换后原图元的坐标会映射到新的位置，其中：</P>
<P>X1=Sx*X+dx&nbsp;<BR>Y1=Sy*Y+dy&nbsp;</P>
<P>3.5.3&nbsp;实用这两个例子的成果&nbsp;</P>
<P>假设我们需要将图形原点的位置移动到（150，300），同时形状放大到原来的3倍，该如何进行变换来实现这样的效果呢？</P>
<P>图&nbsp;22.&nbsp;变换效果<BR>&nbsp;</P>
<P>使用第一个例子的分析结果，先进行缩放变换，再进行平移变换的方程变换：</P>
<P>图&nbsp;23.&nbsp;方程推演<BR>&nbsp;</P>
<P>根据推导可知需先进行3倍的缩放变换，再平移（50，100）个坐标就可以实现指定的变换效果。实现程序如下</P>
<P></P>
<P>//&lt;g&nbsp;transform="&nbsp;scale(3&nbsp;)&nbsp;translate(50，100)"&gt;<BR>AffineTransform&nbsp;rat&nbsp;=&nbsp;svgCanvas.getRenderingTransform();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rat.scale(3,3);<BR>rat.translate(50,100);<BR>svgCanvas.setRenderingTransform(rat);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;</P>
<P>若先进行平移变换，再进行缩放变换的话，根据第二个例子的推导结果：</P>
<P>图&nbsp;24.&nbsp;方程推演<BR>&nbsp;</P>
<P>可知应先进行（150，300）的平移操作，再实现3倍的缩放操作。实现程序如下：</P>
<P></P>
<P>//&lt;g&nbsp;transform="&nbsp;translate(150，300)&nbsp;scale(3&nbsp;)"&gt;<BR>AffineTransform&nbsp;rat&nbsp;=&nbsp;svgCanvas.getRenderingTransform();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rat.translate(150,300);<BR>rat.scale(3,3);<BR>svgCanvas.setRenderingTransform(rat);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;</P>
<P>4.&nbsp;一个常用复合变换实例的实现--定点变换<BR>上边我们分析了&nbsp;Batik&nbsp;实现&nbsp;SVG&nbsp;图形变换的原理和计算方法。下面我们用分析的结果实现一个常用的变换实例：定点变换。变换的种类包括缩放，旋转（一般不考虑定点平移这个概念）。</P>
<P>所谓定点变换就是在图形变换中指定一个固定的点，在变换结束后，该点的位置不发生变化。定点变换在&nbsp;GIS&nbsp;的实际运用中很常见，比如将地图放大到指定倍数而保持地图的某个位置（如：鼠标点击的位置）不发生变化。我们以定点缩放为例描述定点变换的使用方法。</P>
<P>假设我们用(x1,y1)点来做定点变换的基准点进行几何变换，要求实现变换后（x1,y1）的位置不变。</P>
<P>定点变换的基本思想是基于这样一个特性：当图像进行缩放，或旋转变换的时候，坐标原点的位置并不发生变化。定点变换的实现方法就是，先将基准点（x1,y1）平移到原点即做一次[-x1,-y1]变换，进行变换后再将变换后的原点平移到（x1,y1）即再进行一次[x1,y1]变换。</P>
<P>图&nbsp;25.&nbsp;基于（x1,y1）定点变换<BR>&nbsp;</P>
<P>实际编程的时候，我们无需对定点变换做如此复杂的运算。例如可以采用如下的方式实现针对（50,50）的定点变换：</P>
<P></P>
<P>//以（50，50）点为基准点进行几何变换<BR>//&lt;g&nbsp;transform="translate(50，50)&nbsp;……………&nbsp;translate(-50，-50)"&gt;<BR>AffineTransform&nbsp;rat&nbsp;=&nbsp;svgCanvas.getRenderingTransform();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rat.translate(50，50);<BR>//其他变换方式<BR>………………<BR>………………<BR>………………<BR>rat.translate(-50,-50);<BR>svgCanvas.setRenderingTransform(rat);</P></DIV></DIV><img src ="http://www.cnitblog.com/wjh1025/aggbug/6074.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/wjh1025/" target="_blank">WJH</a> 2006-01-07 19:14 <a href="http://www.cnitblog.com/wjh1025/archive/2006/01/07/6074.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大量的SVG示例！</title><link>http://www.cnitblog.com/wjh1025/archive/2006/01/05/6036.html</link><dc:creator>WJH</dc:creator><author>WJH</author><pubDate>Thu, 05 Jan 2006 12:58:00 GMT</pubDate><guid>http://www.cnitblog.com/wjh1025/archive/2006/01/05/6036.html</guid><wfw:comment>http://www.cnitblog.com/wjh1025/comments/6036.html</wfw:comment><comments>http://www.cnitblog.com/wjh1025/archive/2006/01/05/6036.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/wjh1025/comments/commentRss/6036.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/wjh1025/services/trackbacks/6036.html</trackback:ping><description><![CDATA[<A href="http://xml.org.cn/dispbbs.asp?boardID=21&amp;ID=13570">http://xml.org.cn/dispbbs.asp?boardID=21&amp;ID=13570</A><img src ="http://www.cnitblog.com/wjh1025/aggbug/6036.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/wjh1025/" target="_blank">WJH</a> 2006-01-05 20:58 <a href="http://www.cnitblog.com/wjh1025/archive/2006/01/05/6036.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>