0

I have created a polygon using raphael path. The vertices of the polygon can be dragged to stretched to change the shape/size of the polygon.

The test is running here

Now what I want to implement is that if I dblclick on the edge, it should create a new vertex. So that it can act as a dragging point.

Can anyone help me out on identifying the position of a point in the path:

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

and if a mouse event happens on 200,250, how to identify where in the path array, should the new point command fit?

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

OR

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

1 回答 1

2

我的实现略有不同,但如果太多,您可以随时调整它(我实际上在鼠标单击时在多边形中插入新点,只要它可能在纸上)。

一些自定义的 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 个步骤:

  1. 循环遍历多边形的每一侧并获取到该侧和该点的距离
  2. 从较低的距离,假设新创建的点应该插入到 2 个点之间

获取新点的距离

这两个步骤很容易理解,但很难实现(尤其是第一个)。这是详细的第一步。假设你在多边形的每一边上循环(边等于 2 个点),我们需要提供一个包含所有距离的数组,这样我们才能得到最低的距离。

C +-------+ A                                           + M
   \      |             The shortest                   /     The shortest
    \     |             distance is [MG]              /      distance is [MA]
     \  G +--------+ M                        C +----+ A
      \   |                                      \   |
       \  |                                       \  |
        \ |                                        \ |
         \|                                         \|
          + B                                        + B
  1. 您在边上迭代的函数将两两取点,加上新创建的点,即 3 点,但让我们为第一次迭代编写它(例如)
  2. 所以oA和oB是多边形边的2个点,oM是新创建的点
  3. 挖掘你的数学,你应该能够得到oG的坐标,oM在oA和oB组成的线上的翻译点
  4. 一旦你有了 oG 的坐标,有两种情况:
    • oG 在 oA 和 oB 之间
      1. oM 在oA 和 oB 做的边的前面
      2. 所以返回的距离就是 oM 和 oG 的距离
    • oG 在 oA 和 oB 的段之外
      1. oM不是 前面oA 和 oB 做的边
      2. 所以返回的距离是 oM 与 oA 或 oB 之间的距离,只需返回它们中最低的 2
  5. 现在你有 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);
于 2013-08-22T12:16:10.917 回答