SVG <path> 中的随机点
Posted
技术标签:
【中文标题】SVG <path> 中的随机点【英文标题】:Random point inside SVG <path> 【发布时间】:2013-05-20 06:02:33 【问题描述】:这个问题很容易描述。我有一个简单的 SVG 闭合形状,如下所示:
<path d="M435.95,147.99l0.33,0.49l-0.11,1.07l-0.39,0.04l-0.29,-0.15l0.21,-1.4l0.25,-0.05Z"></path>
我想在这个形状内的某个地方随机画一个点。
如何做到这一点?我希望解决方案尽可能简单。
【问题讨论】:
你的形状保证是凸的,还是有凹的区域? 我将您的标题从 "on SVG<path>
"(这很简单)编辑为 "inside SVG <path>
",因为您在问题中写道。如果您真的只想要一个沿形状边界的随机点,请重新编辑它。
可能是凹的。感谢您的编辑,您是正确的,如果我只想要一个沿边界的点,我会使用带有随机数的 getPointAtLength()。
【参考方案1】:
您可以使用getBBox 获取路径的边界框并在该范围内生成一个随机点。然后使用elementFromPoint 和随机点来检查你是否真的超出了形状。
如果任何元素覆盖了路径,则将它们设置为 pointer-events="none" 以便在执行此操作时忽略它们。
【讨论】:
这是个好主意,只是验证交集的部分有点“hackish”。有时所需的元素不在浏览器的视口中,或者在我的情况下,可能有一个随机元素覆盖了对象。假设我们有一个网络应用程序,用户可以在其中放置一个窗口。 上面的方法不依赖于它在浏览器的视口中。【参考方案2】:如果路径是凸的,我们可以用简单的方式来做:
Raphael.el.getRandomPointInsideConvex=function()
if(this.type!='path') return undefined;
//sample two points along the path
var len=this.getTotalLength(),
p1=this.getPointAtLength(Math.random()*len),
p2=this.getPointAtLength(Math.random()*len),
ratio=Math.random();
//get the random point
var x=p1.x+(p2.x-p1.x)*ratio,
y=p1.y+(p2.y-p1.y)*ratio;
return x:x,y:y;
;
你可以这样调用方法:
//el is an element
var r=el.getRandomPointInsideConvex();
//draw a cross at this point to show it.
el.paper.path(['M',r.x-2,r.y,'L',r.x+2,y,'M',r.x,r.y-2,'L',r.x,r.y+2]);
希望对你有帮助。
【讨论】:
好主意。对于未来的读者,我想警告您,此解决方案不会产生统一的选择。这意味着来自某些区域的点被选中的概率更高。 接受的答案将根据需要循环多次,以使边界框中的真正随机点落入形状内。相比之下,这个答案不需要循环,即它只需要一次通过。因此,在一些边缘情况下,这个解决方案可能比接受的答案更快,例如一个非常窄的 45 度椭圆形,其中边界框中的大多数随机点不会在形状内。但是,接受的答案不仅限于凸形,而这个答案是(而且,正如@Rok Kralj 指出的那样,这个答案实际上并没有真正的随机点)。以上是关于SVG <path> 中的随机点的主要内容,如果未能解决你的问题,请参考以下文章