优化:圆弧拉伸夹点时,退化成直线时,保持圆弧正确性

pull/1912/MERGE
ChenX 2 years ago
parent 3f0c18f57c
commit a9d9432dfb

@ -2,25 +2,33 @@
exports[`三点共线 1`] = `
Vector3 {
"x": 0,
"y": 0,
"x": -49999.99999499999,
"y": 1.0000000000015987,
"z": 0,
}
`;
exports[`三点共线 2`] = `0`;
exports[`三点共线 2`] = `6.283165307179587`;
exports[`三点共线 3`] = `1.5707963267948966`;
exports[`三点共线 3`] = `0.000019999999999301362`;
exports[`三点共线 4`] = `0`;
exports[`三点共线 4`] = `50000.000004999994`;
exports[`三点同一位置 1`] = `0`;
exports[`三点同一位置 2`] = `0`;
exports[`三点圆心 1`] = `3.141592653589793`;
exports[`三点圆心 1`] = `
Array [
5,
0,
0,
]
`;
exports[`三点圆心 2`] = `3.141592653589793`;
exports[`三点圆心 2`] = `0`;
exports[`三点圆心 3`] = `0`;
exports[`圆弧偏移 1`] = `
Vector3 {

@ -27,7 +27,7 @@ test("三点圆心", () =>
new Vector3(5, 5, 0),
new Vector3(10, 0, 0)
);
expect(arc.Center.toArray()).toMatchObject([5, 0, 0]);
expect(arc.Center.toArray()).toMatchSnapshot();
expect(arc.StartAngle).toMatchSnapshot();
expect(arc.EndAngle).toMatchSnapshot();
});

@ -34,11 +34,9 @@ export function getCircleCenter(pt1: Vector3, pt2: Vector3, pt3: Vector3)
let temp = A1 * B2 - A2 * B1;
let center = new Vector3();
//判断三点是否共线
if (temp === 0)
if (equaln(temp, 0, 1e-5))
{
//共线则将第一个点pt1作为圆心
center.x = pt1.x;
center.y = pt1.y;
return;
}
else
{

@ -1,6 +1,6 @@
import { Box3, Matrix3, Matrix4, Vector2, Vector3 } from 'three';
import { getArcOrCirNearPts, getCircleCenter, GetTanPtsOnArcOrCircle } from '../../Common/CurveUtils';
import { reviseMirrorMatrix, SetMtxVector } from '../../Common/Matrix4Utils';
import { reviseMirrorMatrix, SetMtxVector, TransformVector } from '../../Common/Matrix4Utils';
import { Status } from '../../Common/Status';
import { ObjectSnapMode } from '../../Editor/ObjectSnapMode';
import { Box3Ext } from '../../Geometry/Box';
@ -598,7 +598,7 @@ export class Arc extends Curve
FromThreePoint(pt1: Vector3, pt2: Vector3, pt3: Vector3)
{
if (!(pt1 && pt2 && pt3))
return;
return this;
let ocsInv = this.OCSInv;
pt1 = pt1.clone().applyMatrix4(ocsInv).setZ(0);
@ -606,6 +606,12 @@ export class Arc extends Curve
pt3 = pt3.clone().applyMatrix4(ocsInv).setZ(0);
let center = getCircleCenter(pt1, pt2, pt3);
if (!center)
{
this.ParseFromBul(pt1.applyMatrix4(this.OCSNoClone), pt3.applyMatrix4(this.OCSNoClone), 1e-5);//faker line
return this;
};
this.Center = center.clone().applyMatrix4(this.OCS);
//用圆心和其中一个点求距离得到半径:
this._Radius = center.distanceTo(pt1);
@ -672,16 +678,49 @@ export class Arc extends Curve
if (indexList.length > 0)
{
this.WriteAllObjectRecord();
let ptsArr = this.GetGripPoints();
let index = indexList[0];
let p = ptsArr[index];
if (p)
if (index > 2)
this.Center = this.Center.add(vec);
else
{
p.add(vec);
if (index > 2)
this.Center = this.Center.add(vec);
else
this.FromThreePoint(ptsArr[0], ptsArr[1], ptsArr[2]);
let p1 = polar(new Vector3, this._StartAngle, this._Radius);
let p2 = polar(new Vector3, this.GetAngleAtParam(0.5), this._Radius);
let p3 = polar(new Vector3, this._EndAngle, this._Radius);
vec = TransformVector(vec.clone(), this.OCSInv).setZ(0);
[p1, p2, p3][index].add(vec);
let center = getCircleCenter(p1, p2, p3);
if (!center)//三点共线 使用faker arc
{
this.ParseFromBul(p1.applyMatrix4(this.OCSNoClone), p3.applyMatrix4(this.OCSNoClone), 1e-5);
this.Update();
return;
}
//起始角度 端点角度
this._StartAngle = angle(p1.clone().sub(center));
this._EndAngle = angle(p3.clone().sub(center));
if (equaln(this._StartAngle, this._EndAngle, 1e-5))//差不多也是三点共线,只不过逃逸了
{
this.ParseFromBul(p1.applyMatrix4(this.OCSNoClone), p3.applyMatrix4(this.OCSNoClone), 1e-5);
this.Update();
return;
}
//用圆心和其中一个点求距离得到半径:
this._Radius = center.distanceTo(p1);
this.Center = center.clone().applyMatrix4(this.OCS);
//求出向量p1->p2,p1->p3
let v1 = p2.clone().sub(p1);
let v2 = p3.clone().sub(p1);
this._Clockwise = v1.cross(v2).z < 0;
this.Update();
}
}

@ -110,23 +110,14 @@ export class RoomWallArc extends RoomWallBase
pts.push(pts[i].clone().setZ(pts[i].z + this._Height));
return pts;
}
MoveGripPoints(indexList: Array<number>, vec: Vector3)
{
if (indexList.length > 0)
{
this.WriteAllObjectRecord();
let ptsArr = this.GetGripPoints();
let index = indexList[0];
let p = ptsArr[index];
if (p)
{
p.add(vec);
if (index > 2)
this.Center = this.Center.add(vec);
else
this.FromThreePoint(ptsArr[0], ptsArr[1], ptsArr[2]);
this.Update();
}
if (index >= 4) index -= 4;
Arc.prototype.MoveGripPoints.call(this, [index], vec);
}
}

Loading…
Cancel
Save