如何将一个多边形直接切成几块?

问题描述 投票:0回答:2

我想用 JavaScript 开发一个游戏“Cut the Shape”。多个具有凸多边形的组件需要根据凸自由面的数量进行裁剪。线条和多边形显示在画布上。 Paper.js 图形加载即可使用。

但是问题出现了,这涉及到多边形相对于绘制的线彼此之间的正确分离,我只是想不出一种方法来做到这一点。

这是一个简单多边形的示例(线条绝对可以是任何,用户自己绘制):

enter image description here

我得到了使用带线的小点将多边形划分为其他多边形的要点:

var polygon = new Path.RegularPolygon(new Point(200, 300), 4, 100);
polygon.strokeColor = 'blue';
polygon.fullySelected = true;

var shapesArray = [];
shapesArray.push(polygon);

function splitShape(path1, path2){
var shapesArrayCopy = path1.slice(0);
shapesArray = [];
for(var i = 0; i < shapesArrayCopy.length; i++){
    var intersections = shapesArrayCopy[i].getIntersections(path2);
    if(intersections.length >= 2){
        var p1 = shapesArrayCopy[i].split(shapesArrayCopy[i].getNearestLocation(intersections[0].point));
        var p2 = shapesArrayCopy[i].split(shapesArrayCopy[i].getNearestLocation(intersections[1].point));
        p1.closed = true;
        p2.closed = true;
        shapesArray.push(Object.assign(p1));
        shapesArray.push(Object.assign(p2));
        path2.visible = false;
    }
    else{
        shapesArray.push(shapesArrayCopy[i])
    }
}

var myPath;

function onMouseDown(event) {
   myPath = new Path();
   myPath.strokeColor = 'black';
   myPath.add(event.point);
   myPath.add(event.point);
}

function onMouseDrag(event) {
    myPath.segments.pop(); 
    myPath.add(event.point);
}

function onMouseUp(event) {
   splitShape(shapesArray, myPath)
   myPath.visible = false;
}

enter image description here

javascript algorithm geometry polygon
2个回答
1
投票

在 2D 中,您只需沿垂直于切割线的方向移动切割即可。如果您的切割线端点是:

p0(x0,y0),p1(x1,y1)
那么线方向是:

dp = p1-p0 = (x1-x0,y1-y0)

将其设为单位:

dp /= sqrt((dp.x*dp.x)+(dp.y*dp.y)

使其等于切割之间间隙的一半:

dp *= 0.5*gap

现在有两个垂直方向:

d0 = (-dp.y,+dp.x)
d1 = (+dp.y,-dp.x)

所以现在只需将

d0
添加到一个切口的所有顶点,并将
d1
添加到另一切口。其用途很简单,您取不位于切割线上的点(例如切割的平均点)
p
并计算(对于多边形切割仅一次):

t = dot(p-p0,d0) = ((p.x-x0)*d0.x)+((p.y-y0)*d0.y)

如果

(t>0)
使用
d0
,如果
(t<0)
使用
d1
,如果
(t==0)
你选择了错误的点
p
,因为它位于切割线上。


0
投票

JSTS 库还可以用于在 Javascript 中用多点线切割/分割多边形。 这是一个对我有用的例子

© www.soinside.com 2019 - 2024. All rights reserved.