美文网首页
js 切割三角形

js 切割三角形

作者: CODERLIHAO | 来源:发表于2020-05-07 18:49 被阅读0次
2020-05-07 18.04.12.gif

前面我说过怎么切割圆形
三角形的切割就是每一条边(注意是线段)与另一个线段的交点的问题
我们把三角形的每一条边看成一个向量,切割的线段也是一个向量,这样就是两个向量求交点问题

image.png
现有向量AB 与向量CD 相交于P点
设A(x1,y1) , B(x2, y2),C(x3,y3) , D(x4, y4) ,P(x,y)
因为向量CP // 向量DP ,向量AP // 向量BP
向量积

向量CP = ( x - x3 ,y - y3 )
向量DP = ( x - x4 ,y - y4 )
所以 (x - x3(y - y4) - (y - y3)(x - x4) = 0
x(y3 - y4) + y(x4 - x3) = x4y3 - x3y4
至此方程1出来了,下面求出方程2

向量AP = ( x - x1 ,y - y1 )
向量BP = ( x - x2 ,y - y2 )
(x - x1(y - y2) - (y - y1)(x - x2) = 0

x(y1 - y2) + y(x2 - x1) = x2y1 - x1y2
两个方程组成方程组
x(y3 - y4) + y(x4 - x3) = x4y3 - x3y4
x(y1 - y2) + y(x2 - x1) = x2y1 - x1y2
用行列式求解

image.png

需要判断D不能等于0

image.png image.png image.png
image.png

这样就求出交点

但是有这种情况


image.png

线段没有相交,但是用向量计算时还是会计算出交点,此时可以用CP+ PD = CD 并且
AP + PB = AB来排除这个点

class TriangleShape extends Shape {

        points = null;
        strokeColor = "#098231";
        fillColor = "#098231";
        cutFillColor = "#098231";
        strokeWidth = 0;


        constructor(option) {
            super(option);
            this.strokeColor = option.strokeColor;
            this.fillColor = option.fillColor;
            this.cutFillColor = option.cutFillColor;
            this.strokeWidth = option.strokeWidth;
            this.points = option.points;
        }

        reset(ctx) {
            this.hitChild = null;
            this.child.length = 0;
            this.isCut = false;
            this.drawSelf(ctx);
        }

        drawSelf(ctx) {
            ctx.beginPath();
            ctx.fillStyle = this.fillColor;
            ctx.moveTo(this.points[0], this.points[1]);
            ctx.lineTo(this.points[2], this.points[3]);
            ctx.lineTo(this.points[4], this.points[5]);
            ctx.closePath();
            ctx.fill();
            ctx.beginPath();
            ctx.strokeStyle = this.strokeColor;
            ctx.lineWidth = this.strokeWidth;
            ctx.moveTo(this.points[0], this.points[1]);
            ctx.lineTo(this.points[2], this.points[3]);
            ctx.lineTo(this.points[4], this.points[5]);
            ctx.closePath();
            ctx.stroke();

            this.drawText("a", this.points[0], this.points[1]);
            this.drawText("b", this.points[2], this.points[3]);
            this.drawText("c", this.points[4], this.points[5]);
        }


        drawText(text, x, y) {
            ctx.beginPath();
            ctx.font = "40px Arial";
            ctx.fillText(text, x, y);
            ctx.stroke();
        }


        onTouchUp(event, ctx) {
            super.onTouchUp(event, ctx);
            this.hitChild = null;
            if (this.isCut) {
                this.drawChild(ctx);
                return;
            }

            const points = this.getPoint();
            if (points && points.length === 2) {
                this.isCut = true;
                const p1 = points[0];
                const p2 = points[1];

                const a = {x: this.points[0], y: this.points[1]};
                const b = {x: this.points[2], y: this.points[3]};
                const c = {x: this.points[4], y: this.points[5]};

                const left = Math.min(Math.min(a.x, b.x), c.x);
                const top = Math.min(Math.min(a.y, b.y), c.y);
                const right = Math.max(Math.max(a.x, b.x), c.x);
                const bottom = Math.max(Math.max(a.y, b.y), c.y);

                const images = this.cutShape(p1, p2);
                this.child.push(new ChildShape(left, top, right - left, bottom - top, images[0]));
                this.child.push(new ChildShape(left, top, right - left, bottom - top, images[1]));
                this.drawChild(ctx);
            } else {
                this.drawSelf(ctx);
            }
        }


        cutShape(p1, p2) {
            const a = {x: this.points[0], y: this.points[1]};
            const b = {x: this.points[2], y: this.points[3]};
            const c = {x: this.points[4], y: this.points[5]};
            return Utils.toTriangleDataURL(a, b, c, p1, p2, this.fillColor, this.cutFillColor, this.strokeColor, this.strokeWidth);
        }

        getPoint() {
            const p = {x: this.cutLine.sx, y: this.cutLine.sy};
            const m = {x: this.cutLine.ex, y: this.cutLine.ey};

            const a = {x: this.points[0], y: this.points[1]};
            const b = {x: this.points[2], y: this.points[3]};
            const c = {x: this.points[4], y: this.points[5]};

            const array = [];
            const point1 = this.crossPoint(a, b, p, m);
            if (point1) {
                array.push(point1);
            }
            const point2 = this.crossPoint(b, c, p, m);
            if (point2) {
                array.push(point2);
            }
            const point3 = this.crossPoint(c, a, p, m);
            if (point3) {
                array.push(point3);
            }
            return array;

        }

         crossPoint(a, b, p, m) {
            const D = (a.y - b.y) * (m.x - p.x) - (b.x - a.x) * (p.y - m.y);
            if (D === 0) {
                //无解
                return;
            }
            const D1 = (b.x * a.y - a.x * b.y) * (m.x - p.x) - (b.x - a.x) * (m.x * p.y - p.x * m.y);
            const D2 = (a.y - b.y) * (m.x * p.y - p.x * m.y) - (p.y - m.y) * (b.x * a.y - a.x * b.y);
            const point = {x: D1 / D, y: D2 / D};
            if (Math.sqrt(Math.pow(point.x - a.x, 2) + Math.pow(point.y - a.y, 2)) + Math.sqrt(Math.pow(point.x - b.x, 2) + Math.pow(point.y - b.y, 2)) > Math.sqrt(Math.pow(b.x - a.x, 2) + Math.pow(b.y - a.y, 2)) ||
                Math.sqrt(Math.pow(point.x - p.x, 2) + Math.pow(point.y - p.y, 2)) + Math.sqrt(Math.pow(point.x - m.x, 2) + Math.pow(point.y - m.y, 2)) > Math.sqrt(Math.pow(p.x - m.x, 2) + Math.pow(p.y - m.y, 2))) {
                return;
            }
            return point;
        }
    }

Demo

相关文章

  • js 切割三角形

    前面我说过怎么切割圆形三角形的切割就是每一条边(注意是线段)与另一个线段的交点的问题我们把三角形的每一条边看成一个...

  • js 切割圆形

    这种类型就是线段与圆的交点问题 设线段就是P P 就是我们的线段,P (x ,y ) , P (x ,y ) 交点...

  • 使用gulp对微信小游戏进行分包

    方案 生成未压缩混淆的游戏整包 wxgame.js 截取中间部分标记切割wxgame.js为两个wxgame.js...

  • js切割和截取

    JS对于字符串的切割截取 对于字符串的切割截取平时所用可能不是特别多,而且分的比较细,所以自备自查。有备无患。 由...

  • 空间

    方形、三角形、弧形、 正、狭长、 高、矮、 透、闭、 对称(西方古典)、漫游(中国园林)、 不规则空间钻石切割法取...

  • JS 数组按指定长度切割,返回一个新的数组集合,比如按照3的倍数

    JS 数组按指定长度切割,返回一个新的数组集合,比如按照3的倍数切割,返回结果为每三个一组

  • webpack ensure异步加载的原理

    webpack ensure有人称它为异步加载,也就人称为代码切割。其实它就是把js模块给独立导出一个js文件,然...

  • JS对于字符串的切割截取

    JS对于字符串的切割截取 (参考文章) 对于字符串的切割截取平时所用可能不是特别多,而且分的比较细,所以自备自查...

  • 前端性能优化

    组件的按需引入 webpack打包 js切割 静态资源使用cnd nginx 开启gzip压缩 合理利用缓存

  • js切割图片切割,碎片化动画展示

    今天上网学习前端小技巧,看到一个酷炫的功能,链接在此。怀着激动的心情,在本地测试了一下,发现效果还不错,兼容性:c...

网友评论

      本文标题:js 切割三角形

      本文链接:https://www.haomeiwen.com/subject/xzxzghtx.html