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

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

@ -2,25 +2,33 @@
exports[`三点共线 1`] = ` exports[`三点共线 1`] = `
Vector3 { Vector3 {
"x": 0, "x": -49999.99999499999,
"y": 0, "y": 1.0000000000015987,
"z": 0, "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[`三点同一位置 1`] = `0`;
exports[`三点同一位置 2`] = `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`] = ` exports[`圆弧偏移 1`] = `
Vector3 { Vector3 {

@ -27,7 +27,7 @@ test("三点圆心", () =>
new Vector3(5, 5, 0), new Vector3(5, 5, 0),
new Vector3(10, 0, 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.StartAngle).toMatchSnapshot();
expect(arc.EndAngle).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 temp = A1 * B2 - A2 * B1;
let center = new Vector3(); let center = new Vector3();
//判断三点是否共线 //判断三点是否共线
if (temp === 0) if (equaln(temp, 0, 1e-5))
{ {
//共线则将第一个点pt1作为圆心 return;
center.x = pt1.x;
center.y = pt1.y;
} }
else else
{ {

@ -1,6 +1,6 @@
import { Box3, Matrix3, Matrix4, Vector2, Vector3 } from 'three'; import { Box3, Matrix3, Matrix4, Vector2, Vector3 } from 'three';
import { getArcOrCirNearPts, getCircleCenter, GetTanPtsOnArcOrCircle } from '../../Common/CurveUtils'; 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 { Status } from '../../Common/Status';
import { ObjectSnapMode } from '../../Editor/ObjectSnapMode'; import { ObjectSnapMode } from '../../Editor/ObjectSnapMode';
import { Box3Ext } from '../../Geometry/Box'; import { Box3Ext } from '../../Geometry/Box';
@ -598,7 +598,7 @@ export class Arc extends Curve
FromThreePoint(pt1: Vector3, pt2: Vector3, pt3: Vector3) FromThreePoint(pt1: Vector3, pt2: Vector3, pt3: Vector3)
{ {
if (!(pt1 && pt2 && pt3)) if (!(pt1 && pt2 && pt3))
return; return this;
let ocsInv = this.OCSInv; let ocsInv = this.OCSInv;
pt1 = pt1.clone().applyMatrix4(ocsInv).setZ(0); pt1 = pt1.clone().applyMatrix4(ocsInv).setZ(0);
@ -606,6 +606,12 @@ export class Arc extends Curve
pt3 = pt3.clone().applyMatrix4(ocsInv).setZ(0); pt3 = pt3.clone().applyMatrix4(ocsInv).setZ(0);
let center = getCircleCenter(pt1, pt2, pt3); 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.Center = center.clone().applyMatrix4(this.OCS);
//用圆心和其中一个点求距离得到半径: //用圆心和其中一个点求距离得到半径:
this._Radius = center.distanceTo(pt1); this._Radius = center.distanceTo(pt1);
@ -672,16 +678,49 @@ export class Arc extends Curve
if (indexList.length > 0) if (indexList.length > 0)
{ {
this.WriteAllObjectRecord(); this.WriteAllObjectRecord();
let ptsArr = this.GetGripPoints();
let index = indexList[0]; let index = indexList[0];
let p = ptsArr[index];
if (p) if (index > 2)
this.Center = this.Center.add(vec);
else
{ {
p.add(vec); let p1 = polar(new Vector3, this._StartAngle, this._Radius);
if (index > 2) let p2 = polar(new Vector3, this.GetAngleAtParam(0.5), this._Radius);
this.Center = this.Center.add(vec); let p3 = polar(new Vector3, this._EndAngle, this._Radius);
else
this.FromThreePoint(ptsArr[0], ptsArr[1], ptsArr[2]); 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(); this.Update();
} }
} }

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

Loading…
Cancel
Save