From 6999cc02999a8388330f400f41e77cd1c22e6e62 Mon Sep 17 00:00:00 2001 From: Zoe Date: Fri, 15 Jun 2018 11:19:34 +0800 Subject: [PATCH] =?UTF-8?q?fix=20#IKIBD=20=E4=BC=98=E5=8C=96=E5=81=8F?= =?UTF-8?q?=E7=A7=BB=E6=96=B9=E5=90=91,=E4=BC=98=E5=8C=96=E8=A1=A5?= =?UTF-8?q?=E5=9C=86=E5=BC=A7=E6=9B=B2=E7=BA=BF=E5=88=87=E5=89=B2=E9=80=89?= =?UTF-8?q?=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Add-on/Offset.ts | 46 +++--------------------- src/Common/CurveUtils.ts | 26 ++++++++++++++ src/GraphicsSystem/OffestPolyline.ts | 54 +++++++++++----------------- 3 files changed, 51 insertions(+), 75 deletions(-) diff --git a/src/Add-on/Offset.ts b/src/Add-on/Offset.ts index 1c35c6bd1..0cef15cd0 100644 --- a/src/Add-on/Offset.ts +++ b/src/Add-on/Offset.ts @@ -1,10 +1,10 @@ import { app } from '../ApplicationServices/Application'; +import { cuOffestDir } from '../Common/CurveUtils'; import { Curve } from '../DatabaseServices/Curve'; +import { IsPointInPolyLine } from '../DatabaseServices/PointInPolyline'; +import { Polyline } from '../DatabaseServices/Polyline'; import { Command } from '../Editor/CommandMachine'; import { PromptStatus } from '../Editor/PromptResult'; -import { Polyline } from '../DatabaseServices/Polyline'; -import { IsPointInPolyLine } from '../DatabaseServices/PointInPolyline'; -import { Vector3 } from 'three'; export class Command_Offset implements Command { @@ -82,24 +82,7 @@ export class Command_TestOffset implements Command Callback: (p) => { if (lastpls) lastpls.forEach(cu => cu.Erase()); - - let ptClose = cu.GetClosestPointTo(p, false); - let toPtVec = p.clone().sub(ptClose); //点击处向量 - let d = cu.GetFistDeriv(ptClose);//切线。 - let dir = Math.sign(toPtVec.clone().cross(d).z); - - if (cu instanceof Polyline) - { - let par = cu.GetParamAtPoint(ptClose); - if (par === Math.floor(par) && par) - { - let fd = cu.GetFistDeriv(par - 0.1); - let fc = toPtVec.cross(fd); - let tmpDir = Math.sign(fd.clone().cross(d).z); - if (dir * fc.z < 0) - dir = tmpDir; - } - } + let dir = cuOffestDir(cu, p) lastpls = cu.GetOffsetCurves(p.distanceTo(cu.GetClosestPointTo(p, !cu.IsClose)) * dir); // let a = cu.GetOffsetCurves(p.distanceTo(cu.GetClosestPointTo(p, !cu.IsClose)) * -dir); @@ -117,25 +100,4 @@ export class Command_TestOffset implements Command } } -export function polylineOffestDir(pl: Polyline, p: Vector3) -{ - let ptClose = pl.GetClosestPointTo(p, false); - let toPtVec = p.clone().sub(ptClose); //点击处向量 - let d = pl.GetFistDeriv(ptClose);//切线。 - let dir = Math.sign(toPtVec.clone().cross(d).z); - if (pl instanceof Polyline) - { - let par = pl.GetParamAtPoint(ptClose); - if (par === Math.floor(par) && par) - { - let fd = pl.GetFistDeriv(par - 0.1); - let fc = toPtVec.cross(fd); - let tmpDir = Math.sign(fd.clone().cross(d).z); - if (dir * fc.z < 0) - dir = tmpDir; - } - } - return dir; - -} diff --git a/src/Common/CurveUtils.ts b/src/Common/CurveUtils.ts index 293c2be23..9feafca47 100644 --- a/src/Common/CurveUtils.ts +++ b/src/Common/CurveUtils.ts @@ -8,6 +8,7 @@ import { Count } from '../Geometry/Count'; import { CurveMap } from '../Geometry/CurveMap'; import { equal, equaln } from '../Geometry/GeUtils'; import { Stand } from '../Geometry/RegionParse'; +import { FixIndex } from './Utils'; //3点获取圆心 export function getCircleCenter(pt1: Vector3, pt2: Vector3, pt3: Vector3) @@ -210,3 +211,28 @@ export function equalCurveAndCurve(cu1: Curve, cu2: Curve) } return false; } +export function cuOffestDir(cu: Curve, p: Vector3) +{ + let ptClose = cu.GetClosestPointTo(p, false); + let toPtVec = p.clone().sub(ptClose); //点击处向量 + let caclCu: Curve = cu; + if (cu instanceof Polyline && cu.Area > 0) + { + let par = cu.GetParamAtPoint(ptClose); + if (equaln(par, Math.floor(par + 0.5)) && par) + { + par = Math.floor(par + 0.5); + let frontCu = cu.GetCurveAtParam(par); + let laterCu = cu.GetCurveAtParam(FixIndex(par - 1, cu.EndParam + 1)); + let lateDerv = laterCu.GetFistDeriv(1); + let refD = Math.sign(toPtVec.clone().cross(lateDerv).z); + let refArea = Math.sign(cu.Area2); + if (refD * refArea <= 0) + caclCu = frontCu; + else + caclCu = laterCu + } + } + let derv = caclCu.GetFistDeriv(ptClose);//切线。 + return Math.sign(toPtVec.clone().cross(derv).z); +} diff --git a/src/GraphicsSystem/OffestPolyline.ts b/src/GraphicsSystem/OffestPolyline.ts index 7db18ad44..373f8964d 100644 --- a/src/GraphicsSystem/OffestPolyline.ts +++ b/src/GraphicsSystem/OffestPolyline.ts @@ -1,6 +1,6 @@ import { Box3, Vector3 } from "three"; import { arrayLast, arrayRemoveIf, arraySortByNumber } from "../Common/ArrayExt"; -import { curveLinkGroup } from "../Common/CurveUtils"; +import { curveLinkGroup, cuOffestDir } from "../Common/CurveUtils"; import { FixIndex } from "../Common/Utils"; import { Arc } from "../DatabaseServices/Arc"; import { Circle } from "../DatabaseServices/Circle"; @@ -84,21 +84,7 @@ export class PolyOffestUtil } private CheckPoint1(pt: Vector3) { - let ptClose = this.m_Polyline.GetClosestPointTo(pt, false); - let toPtVec = pt.clone().sub(ptClose); //点击处向量 - let d = this.m_Polyline.GetFistDeriv(ptClose);//切线。 - let dir = Math.sign(toPtVec.clone().cross(d).z); - - let par = this.m_Polyline.GetParamAtPoint(ptClose); - if (par === Math.floor(par) && par) - { - let fd = this.m_Polyline.GetFistDeriv(par - 0.1); - let fc = toPtVec.cross(fd); - let tmpDir = Math.sign(fd.clone().cross(d).z); - if (dir * fc.z < 0) - dir = tmpDir; - } - console.log(dir, Math.sign(this.m_OffestDist), this.offDir); + let dir = cuOffestDir(this.m_Polyline, pt) return dir === this.offDir; } private optimizeCus(boxCurves: Map, outputCus: Curve[]) @@ -109,9 +95,9 @@ export class PolyOffestUtil //与源线段自交 if (c.IntersectWith(this.m_Polyline, IntersectOption.OnBothOperands).length !== 0) return false; - // return this.CheckPoint1(c.StartPoint); + return this.CheckPoint1(c.StartPoint); //起点终点离源线段的距离必须大于偏移距离 - return this.CheckPoint(c.StartPoint) && this.CheckPoint(c.EndPoint); + // return this.CheckPoint(c.StartPoint) && this.CheckPoint(c.EndPoint); }); //处理在偏移反方向的曲线 @@ -489,32 +475,34 @@ export class PolyOffestUtil if (splitCus.length === 2) //2圆相交应该有2段,否则相切 { + let arc1 = splitCus[0]; + let arc2 = splitCus[1]; let tmpPts = cir.IntersectWith(this.m_Polyline, IntersectOption.OnBothOperands); - let onCu0Pts = tmpPts.filter(p => splitCus[0].PtOnCurve(p)); - let onCu1Pts = tmpPts.filter(p => splitCus[1].PtOnCurve(p)); - //选择和源线段不相交的那段圆弧 + let onCu0Pts = tmpPts.filter(p => arc1.PtOnCurve(p)); + let onCu1Pts = tmpPts.filter(p => arc2.PtOnCurve(p)); + let lastCu = arrayLast(this.m_RetCurves); + + if (!equal(arc1.StartPoint, lastCu.EndPoint)) + arc1.Reverse(); + if (!equal(arc2.StartPoint, lastCu.EndPoint)) + arc2.Reverse(); + //优先选择和源线段不想交的圆弧,如果都相交或者都不相交,选择和最后一段切线接近的圆弧 let cu: Arc; - if (onCu0Pts.length === 0) - { - cu = splitCus[0]; - } - else if (onCu1Pts.length === 0) + if (onCu0Pts.length === onCu1Pts.length) { - cu = splitCus[1] + let derv = lastCu.GetFistDeriv(1); + let derv1 = arc1.GetFistDeriv(0); + let derv2 = arc2.GetFistDeriv(0); + cu = derv.angleTo(derv1) < derv.angleTo(derv2) ? arc1 : arc2; } else { - //TODO:先用第一段 - cu = splitCus[0]; + cu = onCu0Pts.length < onCu1Pts.length ? arc1 : arc2; } //防止加入0长度圆弧 if (equaln(cu.Length, 0, 1e-6)) return; - let lastCu = arrayLast(this.m_RetCurves); - //如果不是首尾相连,就反转后在存入数组 - if (!equal(cu.StartPoint, lastCu.EndPoint)) - cu.Reverse(); this.m_RetCurves.push(cu); this.m_Contours.push(this.BuildContour(cu)); }