前面我说过怎么切割圆形
三角形的切割就是每一条边(注意是线段)与另一个线段的交点的问题
我们把三角形的每一条边看成一个向量,切割的线段也是一个向量,这样就是两个向量求交点问题
现有向量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
用行列式求解
需要判断D不能等于0
image.png image.png image.pngimage.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;
}
}
网友评论