我已经使用拉斐尔路径创建了一个多边形。可以拖动多边形的顶点以将其拉伸以更改多边形的形状/大小。

测试正在运行here

现在,我要实现的是,如果我在边缘上双击,它将创建一个新的顶点。这样它就可以作为拖动点。

任何人都可以帮助我确定路径中点的位置:

var p = r.path("M100,300L100,100L250,300z");


并且如果在200,250上发生鼠标事件,那么如何识别路径数组中的新位置应该适合新的point命令?

var p = r.path("M100,300L200,250L100,100L250,300z");


要么

var p = r.path("M100,300L100,100L200,250L250,300z");

最佳答案

我的实现略有不同,但是如果太多的话,您总是可以对其进行调整(实际上,只要在纸上的任意位置单击鼠标,我都会在多边形中插入新点)。

一些自定义Raphael方法


Raphael.el.MakeDraggable:添加处理程序以拖动任何元素(即点或多边形)
Raphael.el.InsertPoint:在多边形中插入给定点(参数)


我的观点


Paper.circle()制成
可以用鼠标拖动




var oPaper = Raphael('#paper', '100%', '100%');
var oPoint = oPaper.circle(nX, nY, nRadius);
oPoint.MakeDraggable();


我的多边形


Paper.path()制成
oPolygon.data()绑定到包含其点的集合
可以用鼠标拖动




var oPaper = Raphael('#paper', '100%', '100%');
var oPolygon = oPaper.path(sPath);
oPolygon.InsertPoint(oPoint);


数学

为了将新创建的点插入到多边形的路径中,我遵循了以下两个步骤:


在多边形的每一边上循环并获取到该边和该点的距离
从较低的距离开始,假设应该在两个点之间插入新创建的点


获取新点的距离

这两个步骤很容易理解,但是很难实现(尤其是第一步)。这是详细的第一步。假设您要遍历多边形的每一侧(一侧等于2点),我们需要以所有距离填充一个数组,以便获得最低的距离。

C +-------+ A                                           + M
   \      |             The shortest                   /     The shortest
    \     |             distance is [MG]              /      distance is [MA]
     \  G +--------+ M                        C +----+ A
      \   |                                      \   |
       \  |                                       \  |
        \ |                                        \ |
         \|                                         \|
          + B                                        + B



遍历侧面的函数将点二乘二,再加上3点的新创建点,但让我们为第一次迭代编写它(例如)
所以oA和oB是多边形侧面的2个点,而oM是新创建的点
挖掘数学,您应该能够获得oG的坐标,即oA和oB所形成的直线上oM的转换点
一旦有了oG的坐标,就有2种情况:

oG在oA和oB之间

oM在oA和oB制成的一面的前面
所以返回的距离就是oM和oG之间的距离

oG在oA和oB所组成的部分之外

oM不在oA和oB的侧面
因此,返回的距离就是oM与oA或oB之间的距离,只需返回它们中的最小值2


现在您有1个距离,在多边形的每侧重复一次即可得到其他


现在,包含距离的数组应包含oM与多边形边之间的所有距离。我们需要找到较低的值(可以有多个具有相同值的值)。因此,在其上循环并构建另一个包含最低距离索引的数组。

确定哪一方是正确的

一旦有了这个新数组,请检查其长度:


长度为1:表示您的oM点在侧面的前面。您有了边的索引,继续并将点插入到多边形的数据中
长度为2:表示您的oM点不在侧面前方。您有2个索引,将它们视为点索引,有2个点构成了边,与上面相同,现在您可以将点插入到多边形的数据中
长度为3+(我相信您不需要):特殊情况,例如圆形(具有很多点)和类似正方形的多边形,可以将点插入到正中央


一些更多的东西

// Don't forget to bind points to their polygon
oPolygon.data('points', oPoints);  // oPoints is a Raphael set containing the points

// There are different approaches, mine was to bind the other way as well
oPoint.data('polygon', oPolygon);

关于javascript - 确定拉斐尔路径上的点的位置,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18363660/

10-12 13:07