0

编辑:

我终于找到了一种侵蚀和扩张多边形(偏移)的方法,以便使用 Clipper 库创建新几何: https ://sourceforge.net/projects/jsclipper/

Javascript Clipper 的现场演示:http: //jsclipper.sourceforge.net/5.0.2.1/main_demo.html

Clipper 只能处理多边形或多多边形(例如带孔的多边形),因此要与其他 SVG 格式的图形对象一起工作,必须将它们转换为直线。至少路径很容易使用path.getTotalLength()path.getPointAtLength()http://whaticode.com/2012/02/01/converting-svg-paths-to-polygons/)转换为行。

另一种可能性是使用这种类似的技术(不创建新几何): https ://stackoverflow.com/a/12723835/1691517


有什么方法可以通过 Javascript 腐蚀和扩张 SVG 中的形状?

我有以下 SVG 示例:http: //jsfiddle.net/timo2012/2S4Kt/1/

共有三种形状,蓝色是原始的,绿色是侵蚀的(变细的)和红色的是膨胀的(加粗的)。它们是在 Illustrator 中制作的。

我测试过侵蚀和扩张过滤器,但效果不是很好: https ://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/examples/feMorphology.svg

在互联网上搜索了几个小时后,我只找到了有关位图图像侵蚀和膨胀的示例,但没有找到有关矢量形状的示例。

我已经成功地在 Python 中使用 Shapely(http://toblerity.github.com/shapely/manual.html)扩张和侵蚀 SVG 多边形,方法是通过 Ajax 调用向 PHP 脚本发送路径点,从而使 system() 调用 Python 脚本,但是这种方法很慢,并且需要服务器完成可以在客户端完成的工作。

这是我在 Python 中进行膨胀和腐蚀的代码(如您所见,它很短):

#!/usr/bin/python26

from shapely.geometry import Polygon
from shapely.geometry import MultiPolygon

import sys

if len(sys.argv)>2:
  inset=eval(sys.argv[1])
  coords=eval(sys.argv[2])
else:
  sys.exit()

bowtie = Polygon(coords)
clean = bowtie.buffer(inset)
clean = clean.simplify(1, preserve_topology=False)
if clean.length>0:
  if clean.geom_type=="MultiPolygon":
    for n in range(0, len(clean)):
      print list(clean[n].exterior.coords)
      #print "\n"
  elif clean.geom_type=="Polygon":
    print list(clean.exterior.coords)

还可以找到这个文件,它试图用数学术语定义扩张和腐蚀: http ://en.wikipedia.org/wiki/Mathematical_morphology

有一句话“二元形态学的基本思想是用一个简单的、预定义的形状探测图像,得出关于这个形状如何适合或错过图像中的形状的结论。这个简单的“探测”被称为结构元素,并且本身就是一个二值图像(即空间或网格的子集)。”

我假设这种方法可以用于变形矢量形状,但是如何......

编辑:回复中的一条评论提出了使用过滤器而不是创建新几何图形的可能问题:如果有人想将拖动手柄添加到多边形点,那么拖动手柄可能似乎在错误的位置。这是可以接受的,因为给人的印象是原始路径数据没有受到影响,这实际上是过滤器的情况,但是 - 经过进一步测试 - 证明质量是一个更大的问题。根据这个这个SVG 过滤器使用矢量图形对象的像素表示而不是路径数据本身,这导致看起来不太好看

EDIT2:可能的解决方法:此页面中的一个答案使我使用可变宽度笔画和蒙版来实现此问题的美观解决方法。我做了一些测试并实现了类似Adob​​e Illustrator 的 Offset Path Effect

4

2 回答 2

1

你真的测试过 SVG 的原生过滤器吗?这看起来足够接近:

<svg width="612" height="792" viewBox="0 0 612 792" xmlns="http://www.w3.org/2000/svg">

  <defs>
    <filter id="erode">
      <feMorphology operator="erode" in="SourceGraphic" radius="12" />
    </filter>
    <filter id="dilate">
      <feMorphology operator="dilate" in="SourceGraphic" radius="8" />
    </filter>
      <path id="original_path" d="M193.193,85c23.44,0.647,45.161,0.774,62,12c1.596,1.064,12,11.505,12,13
    c0,2.941,8.191,5.669,3,12c-3.088,3.767-6.01-0.758-11-1c-19.56-0.948-33.241,12.296-33,34c0.163,14.698,8.114,24.492,4,41
    c-1.408,5.649-6.571,15.857-10,21c-2.484,3.726-7.898,10.784-12,13c-4.115-11.677,2.686-27.29-6-35c-6.693-5.942-20.021-4.051-26,1
    c-13.573,11.466-11.885,41.492-7,58c-5.8,1.772-18.938,7.685-23,12c-6.752-10.805-15.333-17.333-24-26c-3.307-3.307-9.371-12-15-12
    c-16.772,0-13.963-15.741-13-28c1.283-16.324,1.727-28.24,4-42c1.276-7.72,8-16.411,8-23c0-7.416,15.945-29,23-29
    c4.507,0,17.678-8.701,24-11C164.853,90.76,178.27,88.546,193.193,85"/>
  </defs>
  <use xlink:href="#original_path" fill="#f00" filter="url(#dilate)"></use>    
  <use xlink:href="#original_path" fill="blue"></use>
  <use xlink:href="#original_path" fill="#1CFF00" filter="url(#erode)"></use>    
</svg>

过滤器上有一些剪裁dilate似乎无法通过增加过滤器区域来解决,但除此之外它非常接近您的插画渲染。当然胜过渲染服务器端。

http://jsfiddle.net/5Qv5v/

于 2012-10-02T06:26:34.430 回答
1

你可以通过结合使用不同的笔划宽度来获得你想要的东西clip-pathor mask。这是一个示例,有关它的构造方式的一些解释请参见此处此处(向上或向下箭头以查看该示例中的其他幻灯片)。

但是它并没有给你新的几何,只是看起来像新的几何。

于 2012-10-02T08:05:50.470 回答