查找平行或偏移SVG路径

时间:2018-11-21 12:25:43

标签: javascript math svg polygon

我需要一个并行的SVG路径。 我的路径为'M0 0 H50 A20 20 0 1 0 100 50 v25 C50 125 0 85 0 85 z'。 设置“偏移”为2px。

原始路径O / P: Path Image 进一步细分时的路径细分:

val swidConverter = new StringIndexer()
  .setInputCol("id")
  .setOutputCol("idIndex").fit(df)

val idDf = spark.sparkContext.parallelize(
            swidConverter.labels.zipWithIndex
        ).toDF("id", "idIndex").repartition(PARTITION_SIZE) // set the partition size depending on your data size.

// Joining the idDf(DataFrame) with the actual Data.
val indexedDF = df.join(idDf,idDf.col("id")===df.col("id")).select("idIndex","product_id","rating")

val als = new ALS()
  .setMaxIter(5)
  .setRegParam(0.01)
  .setUserCol("idIndex")
  .setItemCol("product_id")
  .setRatingCol("rating")

val model = als.fit(indexedDF)
val resultRaw = model.recommendForAllUsers(4)

// Joining the idDf(DataFrame) with the Result to get the original ID from the indexed Id.
val resultDf = resultRaw.join(idDf,resultRaw.col("idIndex")===idDf.col("idIndex")).select("id","recommendations")

找到单个段或整个段的偏移路径的任何算法或方法?

更新的图像: 红线代表偏移的SVG图像,我需要获取。 Example Offset SVG Path

2 个答案:

答案 0 :(得分:4)

算法解决方案

抵消线是相对琐碎的。对于圆弧,可以通过将两个半径更改相同的值来解决。 (您仍然必须找到终点。)

问题是贝塞尔曲线。有一个库bezier.js用数学方法解决了这个问题。有关背景知识,请参阅Pomax随附的“贝塞尔曲线上的底漆”,尤其是curve offsetting上的章节。

正如那里指出的那样,不可能找到一条抵消另一条曲线的贝塞尔曲线。您需要将其分为“更简单”的子部分。该库实现了再次组合这些部分并返回偏移路径.offset(d)的功能。

实用解决方案

矢量局部GUI实现了这种功能。以下针对Inkscape进行了描述,但是我确信Adobe Illustrator(也许还有Sketch)可以或多或少地做到这一点。

  • 绘制路径。 Inkscape有一个“ XML编辑器”,您可以在其中直接输入路径定义字符串。
  • 删除填充并定义笔划,其宽度是要获得的偏移量的两倍。
  • 从“路径”菜单中选择“笔触路径”。
  • 从“路径”菜单中选择“分离”。
  • 现在您有两条(填充的)路径,其中一条向外部偏移,一条向内部偏移;丢弃不需要的东西。

请注意,您的路径定义无效。点[50,0]和[100,50]之间的圆弧的半径为20,但是两个点之间的弧距为70.71。按照spec,该路径改为绘制为

M 0,0 H 50 A 35.3553,35.3553 0 1 0 100,50 V 75 C 50,125 0,85 0,85 Z

如果我用Inkscape找到以2插入的路径,我会得到

M 2,2 H 45.7988 C 34.2583,16.6514 35.0764,37.9045 48.5859,51.4141 62.0955,64.9236 83.3486,65.7417 98,54.2012
V 74.1094 C 73.6278,98.1373 49.7442,100.409 31.6426,96.7891 14.9635,93.4533 3.8673,85.3962 2,83.9785 Z

请注意,Inkscape已为弧段计算了三次Bezier近似值。您可以简单地通过将半径增加2来更改为圆弧,更改大圆弧标记并保留端点:

M 2,2 H 45.7988 A 37.3533 37.3533 0 0 0 98,54.2012
V 74.1094 C 73.6278,98.1373 49.7442,100.409 31.6426,96.7891 14.9635,93.4533 3.8673,85.3962 2,83.9785 Z

答案 1 :(得分:2)

我知道您有这条路,您需要在边框后面画一条线。我的解决方案是将<feMorphology>过滤器与operator="erode"一起使用。我希望这就是您所需要的。

<svg viewBox="-10 -10 120 120" width="300">
 <defs>
   
<filter id="erode">
<feMorphology in="SourceAlpha" result="eroded"
operator="erode" radius="2"/>
<feFlood flood-color="white" result="white" />
<feComposite in ="white" in2="eroded" operator="in" />
</filter>

   
<filter id="erode1">
<feMorphology in="SourceAlpha" result="eroded1"
operator="erode" radius="3"/>


</filter>
<path id="g" d="M0, 0
         H50
         A20, 20, 0, 1, 0, 100, 50
         V75
         C50, 125, 0, 85, 0, 85" />
</defs>

<use xlink:href="#g" />
<use xlink:href="#g" filter="url(#erode)" /> 
<use xlink:href="#g" filter="url(#erode1)" /> 
</svg>