【发布时间】:2015-04-22 16:24:36
【问题描述】:
在我的项目中,我从 pathes 创建了河流。而且由于我的 大笔画宽度 它非常衣衫褴褛:
我已经四处搜寻了。但我发现的唯一东西是stroke-linejoin: round;。正如你在这里看到的:
好多了,但我还是不满意。
有什么办法可以得到一条真正平滑的线。或者假设也有一个均匀的“rounder” linejoin?
【问题讨论】:
标签: svg path smoothing topojson
在我的项目中,我从 pathes 创建了河流。而且由于我的 大笔画宽度 它非常衣衫褴褛:
我已经四处搜寻了。但我发现的唯一东西是stroke-linejoin: round;。正如你在这里看到的:
好多了,但我还是不满意。
有什么办法可以得到一条真正平滑的线。或者假设也有一个均匀的“rounder” linejoin?
【问题讨论】:
标签: svg path smoothing topojson
一个有趣的方向是利用 d3.svg.line 从 geoJSON 特征的坐标生成路径,此时您将能够使用 D3 的插值方法。
参见 E. Meeks 的 D3js-Topojson : how to move from pixelized to Bézier curves? 和 Geodata to d3.svg.line interpolation,以及 Crispy edges with topojson?。
编辑: 有一个minimal stand alone case study for line smoothing,您可以通过其关联的 gist 的 git 存储库 fork。 d3.svg.line 的想法以及用于线条平滑的y 坐标的插值来自 E.Meeks。 E. Meeks 解释了他的方法here。
Edit2 & 解决方案: Í 突然想起topojson 是在哪里动态转换成geojson 的。执行以下操作,您可以使用 topojson 文件并最终获得贝塞尔曲线,并根据您的选择进行推断。以下将起作用:
d3.json("./world-110m.json", function(data){
console.log(data)
var geojson = topojson.feature(data, data.objects.countries);
var newJson = newgeoson(geojson);
console.log(JSON.stringify(newJson))
d3.select("body").append("svg").attr("id","world")
.selectAll("path")
.data(newJson)
.enter()
.append("path")
.style("stroke-width", 1)
.style("stroke", "black")
.style("fill-opacity", .5)
.attr("d", d3.svg.line()
.x(function(d){ return d[0] })
.y(function(d){ return d[1] }).interpolate("cardinal"))
.style("fill", "#7fc97f");
})
【讨论】:
console.log(JSON.stringify(d)) 并检查数据。通用解决方案已完成,您的代码触手可及。
如果您对stroke-linejoin:round不满意
你可以考虑创建path outline,
但如果您尝试使用cubic beziers 来平滑您的路径,可能会更容易。
【讨论】:
如果您对它的外观不满意,那么在我看来问题在于您的河流定义的点太少。
您用来平滑路径的任何技术(例如曲线拟合算法)都可能导致您的河流表示比您现在拥有的更不准确。
【讨论】: