如何判断鼠标指针是否位于贝塞尔曲线和直线定义的路径内?

发布于 2024-11-16 11:31:38 字数 222 浏览 1 评论 0原文

我有一条由多条贝塞尔曲线和直线段组成的闭合路径。如何判断鼠标指针的当前位置是在路径内部还是外部?

鼠标离开该区域的示例:
on mouse left

鼠标进入该区域的示例:
鼠标输入

I have a closed path consisting of multiple Bezier curves and straight line segments. How can I tell whether the current position of my mouse pointer is inside or outside the path?

Example of mouse leaving the area:
on mouse leave

Example of mouse entering the area:
on mouse enter

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烟花易冷人易散 2024-11-23 11:31:38

首先,您应该检查您正在使用的图形库是否已经提供了此命中测试。

如果您必须自己编码,那么完全精确的答案将需要求解二次或三次方程(取决于贝塞尔曲线的阶数)来确定与这些路径的交点。似乎有一篇论文正是这个问题

不过,我认为构建路径的线性近似(即密集评估路径)然后使用标准 多边形内点测试。这可以精确到您选择的任何容差(例如一个像素)。

First you should check if the graphics library you're using already provides this hit-testing.

If you have to code it yourself, then a completely precise answer would require solving quadratic or cubic equations (depending on the degree of your Bezier curves) to determine the intersection with these paths. There seems to be a paper on exactly this problem.

However I think it would be much more sensible to build a linear approximation to your path (i.e. evaluate the path densely) and then use a standard point-in-polygon test. This can be accurate to whatever tolerance you choose (e.g. one pixel).

十年九夏 2024-11-23 11:31:38

如果区域相对较小,您可以从鼠标位置开始运行洪水填充。如果洪水填充超出边界框(您可以预先计算),则它位于该区域之外。

请参阅:http://en.wikipedia.org/wiki/Flood_fill

If the regions are relatively small, you could run a floodfill starting from the mouse location. If the floodfill goes outside of a bounding box (which you can precompute) then it's outside of the region.

See: http://en.wikipedia.org/wiki/Flood_fill

同展鸳鸯锦 2024-11-23 11:31:38

要测试某个点是在贝塞尔曲线路径内部还是外部,请从该点向任意方向绘制一条线,并计算该线穿过该路径的次数。如果数字是奇数,那么你在里面,如果数字是偶数,那么你在外面。

因此,内部测试可以重新表示为交叉测试。可以通过多种方式解决交叉路口问题。一种相对简单的方法是使用 deCasteljau 算法用直线段来近似贝塞尔曲线图块,将贝塞尔曲线相交测试简化为一系列直线相交测试。

请注意,您可以在计算中采取多种捷径。例如,如果您正在绘制的线完全位于给定贝塞尔曲线面片控制点的边界框之外,那么您可以假设它不会穿过该面片。当使用 deCasteljau 递归分割曲线时,您可以利用这个特定的快捷方式来丢弃不会与线段相交的曲线的分割部分。

To test whether a point is inside or outside a bezier path, draw a line in any direction from the point, and count the number of times the line crosses the path. If the number is odd, then you are inside, if it is even then you are outside.

So, an inside-ness test can be re-expressed as an intersection test. Intersections can be tackled in several ways. A relatively simple approach is to approximate your bezier patches with straight line segments using deCasteljau's algorithm, reducing the bezier-line intersection test to a series of line-line intersection tests.

Note that you can take several shortcuts in your calculation. If, for example, the line you're drawing lies completely outside the bounding box of a given bezier patch's control points, then you can assume that it's not going to cross the patch. You can take advantage of this particular shortcut when recursively splitting your curves with deCasteljau to discard split sections of curves that are not going to intersect your line segment.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文