Svg简单转换

时间:2017-01-26 23:45:27

标签: delphi svg transformation algebra

我有一个简单的svg,有3条路径:红色,蓝色和黄色。 我想:缩放所有形状(例如0.3)并仅旋转红色+蓝色(例如90度)。 旋转点应该是红色路径的中间。 在这些操作之后,我希望黄色形状与红色路径的距离为原始距离缩放0.3。

我的尝试是:

  1. 计算红色路径的中间位置;
  2. 翻译原点(0,0),翻译为(-redCenterPoint.x, - redCenterPoint.y)
  3. 将红色路径缩放0.3
  4. 通过translate(redCenterPoint.x,redCenterPoint.y)
  5. 移回红色路径
  6. 通过计算blueCenter,yellowCenter
  7. 重复相同的蓝色和黄色

    我的问题是:如何保持原始图像结构但缩放0.3并旋转90? - 蓝色路径与红色路径接触,黄色与原始距离缩放0.3。

    我看到如果我考虑所有3个形状的redCenterPoint,那么该组看起来与原始相同但缩放,看起来是正确的。 我想知道使用第一种方法做同样的事情。

    enter image description here

    svg文件:

     <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1">
    <path
       style="opacity:1;fill:#ff0000"
       d="m 146.98669,417.50473 561.36408,0 0,206.40686 -561.36408,0 z"
       id="red"
       inkscape:label="#table" />
    <path
       style="opacity:1;fill:#0000ff"
       d="m 641.11218,339.32031 65.67491,0 0,82.87548 -65.67491,0 z"
       id="blue" />
    <path
       style="opacity:1;fill:#ffff00"
       d="m 764.69525,515.63883 55.28473,-55.28473 46.43917,46.43918 -55.28473,55.28472 z"
       id="yellow"
       inkscape:connector-curvature="0"
       inkscape:label="#yellow" />
    
    使用Riversoft组件进行渲染SVG的delphi中的

    代码:

    redBounds: TSVGRect;
    redCenterPoint: TPointF;
    redMatrix: TSVGMatrix
    
    redBounds := (svgDoc.SVG.AllItems['red'] as TSVGGraphicElement).BoundsRect;
    
     redCenterPoint.x := bDiamond.Left + (bDiamond.Width) / 2;
     redCenterPoint.y := bDiamond.Top + (bDiamond.Height) / 2;
    
     redMatrix := CreateTranslateRSMatrix(-redCenterPoint.x, -redCenterPoint.y);
    
      redMatrix := RSMatrixMultiply(redMatrix,
        CreateRotationRSMatrix(TPoint(0,0), DegToRad(90)));
    
      redMatrix := RSMatrixMultiply(redMatrix,
        CreateScaleRSMatrix(0.3, 0.3));
    
      redMatrix := RSMatrixMultiply(redMatrix,
        CreateTranslateRSMatrix(redCenterPoint.x, redCenterPoint.y));
    
        (svgDoc.SVG.AllItems['red'] as TSVGGraphicElement)
          .Matrix := mainMatrix;
    

1 个答案:

答案 0 :(得分:0)

您正在做的是保持每个形状的中心不变。那不是你想要做的。您希望保持整个形状的中心不变。这就是你在第二次尝试中所做的事情,你将红色中心应用于所有3个形状,这就是它看起来更好的原因。您可能想要选择一个不同的中心,并且有各种算法可以做到这一点,甚至可以将原点保留在原点(根本不需要移动中心)。但是你必须将同一个中心(无论你选择的是什么)应用到所有形状上以达到你想要的效果,这也适用于旋转(尽管在你的情况下你只对两个形状应用旋转)。但是,旋转中心不必与缩放中心相同。

对于在每种情况下计算新中心的最有效操作,我会使用重心计算,但只是简单的中心平均值也能很好地工作。