diff --git a/src/DatabaseServices/PointInPolyline.ts b/src/DatabaseServices/PointInPolyline.ts index 044102e79..aab02f8ff 100644 --- a/src/DatabaseServices/PointInPolyline.ts +++ b/src/DatabaseServices/PointInPolyline.ts @@ -1,11 +1,12 @@ import { Vector2, Vector3 } from 'three'; - import { angle, equal, equaln } from '../Geometry/GeUtils'; import { IntersectOption } from '../GraphicsSystem/IntersectWith'; import { Arc } from './Arc'; +import { Circle } from './Circle'; import { Line } from './Line'; import { Polyline } from './Polyline'; + /** * 点在扇形内部,提供一个简单实现的版本. * 优化版本请参照:http://www.cnblogs.com/miloyip/archive/2013/04/19/3029852.html @@ -152,3 +153,40 @@ function IsPointInPolygon(pt: Vector3, pts: Vector2[]) return crossings % 2 === 1; } + + +/** + *rect为凸四边形 + * @param {Polyline} rect + * @param {Vector3} pt + */ +function isPointInRect(rect: Polyline, pt: Vector3) +{ + let dir: number = 1; + for (let i = 0; i < rect.EndParam; i++) + { + let p = rect.GetPointAtParam(i); + let firstDerv = rect.GetFistDeriv(i); + let vec = pt.clone().sub(p); + if (i === 0) + { + dir = Math.sign(firstDerv.cross(vec).z); + } + else + { + if (dir != Math.sign(firstDerv.cross(vec).z)) + { + return false; + } + } + } + return true; +} + +export function ptInRectOrCircle(reg: Circle | Polyline, pt: Vector3) +{ + if (reg instanceof Circle) + return reg.PtInCurve(pt); + else + return isPointInRect(reg, pt); +} diff --git a/src/GraphicsSystem/BoolOperateUtils.ts b/src/GraphicsSystem/BoolOperateUtils.ts index b24c18622..1480c48b7 100644 --- a/src/GraphicsSystem/BoolOperateUtils.ts +++ b/src/GraphicsSystem/BoolOperateUtils.ts @@ -1,13 +1,13 @@ import { Vector3 } from 'three'; +import { Arc } from '../DatabaseServices/Arc'; import { Circle } from '../DatabaseServices/Circle'; import { Curve } from '../DatabaseServices/Curve'; import { Ellipse } from '../DatabaseServices/Ellipse'; +import { Line } from '../DatabaseServices/Line'; +import { ptInRectOrCircle } from '../DatabaseServices/PointInPolyline'; import { Polyline } from '../DatabaseServices/Polyline'; +import { equaln } from '../Geometry/GeUtils'; import { IntersectOption } from './IntersectWith'; -import { app } from '../ApplicationServices/Application'; -import { equal, equaln } from '../Geometry/GeUtils'; -import { Line } from '../DatabaseServices/Line'; -import { Arc } from '../DatabaseServices/Arc'; export enum BoolOpeartionType { @@ -89,12 +89,12 @@ export function isTargetCurOutOrOnSourceCur2(sourceCur: Polyline | Circle, targe return IsPtsAllOutOrOnReg(sourceCur, pts); } //判断点点是否全部都在封闭区域外或者在曲线上 -function IsPtsAllOutOrOnReg(sourceReg: Polyline | Circle | Ellipse, pts: Vector3[]) +export function IsPtsAllOutOrOnReg(sourceReg: Polyline | Circle, pts: Vector3[]) { return pts.every(pt => { //是否点在封闭曲线内 - return sourceReg.PtOnCurve(pt) || !sourceReg.PtInCurve(pt); + return sourceReg.PtOnCurve(pt) || !ptInRectOrCircle(sourceReg, pt); }) } @@ -127,12 +127,6 @@ export function TargetCurPosForSourceCur(sourceCur: Polyline | Circle | Ellipse, }) if (noStartI) caclPts.push(targetCur.StartPoint); if (noEndI) caclPts.push(targetCur.EndPoint); - // caclPts.forEach(p => - // { - // let c = new Circle(p, 0.5); - // c.ColorIndex = 2; - // app.m_Database.ModelSpace.Append(c); - // }) onSrc = caclPts.every(pt => sourceCur.PtOnCurve(pt)); if (!onSrc) { @@ -148,3 +142,16 @@ export function TargetCurPosForSourceCur(sourceCur: Polyline | Circle | Ellipse, } +export function targetOnSource(sourceCur: Polyline | Circle, targetCur: Arc | Line) +{ + let onSrc = false; + let pts = targetCur.IntersectWith(sourceCur, IntersectOption.OnBothOperands); + if (pts.length === 0) + { + onSrc = sourceCur.PtOnCurve(targetCur.StartPoint); + } + else + { + + } +} diff --git a/src/GraphicsSystem/OffestPolyline.ts b/src/GraphicsSystem/OffestPolyline.ts index 964515906..eaffd1340 100644 --- a/src/GraphicsSystem/OffestPolyline.ts +++ b/src/GraphicsSystem/OffestPolyline.ts @@ -1,18 +1,18 @@ -import { Vector3, Box3 } from "three"; +import { Vector3 } from "three"; import { arrayLast } from "../Common/ArrayExt"; -import { Vec2DTo3D, Vec3DTo2D, curveLinkGroup, getCirAngleByChordAndTangent } from "../Common/CurveUtils"; +import { curveLinkGroup, getCirAngleByChordAndTangent, Vec2DTo3D, Vec3DTo2D } from "../Common/CurveUtils"; import { FixIndex } from "../Common/Utils"; import { Arc } from "../DatabaseServices/Arc"; import { Circle } from "../DatabaseServices/Circle"; import { Contour } from "../DatabaseServices/Contour"; import { Curve } from "../DatabaseServices/Curve"; import { Line } from "../DatabaseServices/Line"; +import { ptInRectOrCircle } from "../DatabaseServices/PointInPolyline"; import { Polyline } from '../DatabaseServices/Polyline'; -import { equal, equaln, greater } from "../Geometry/GeUtils"; -import { isTargetCurInOrOnSourceCur, isTargetCurOutOrOnSourceCur, TargetCurPosForSourceCur, isTargetCurOutOrOnSourceCur2 } from "./BoolOperateUtils"; +import { equal, equaln } from "../Geometry/GeUtils"; +import { IsPtsAllOutOrOnReg, isTargetCurInOrOnSourceCur, isTargetCurOutOrOnSourceCur } from "./BoolOperateUtils"; import { IntersectOption } from "./IntersectWith"; import { LinkSelf } from "./LinkSelft"; -import { app } from "../ApplicationServices/Application"; interface offestRes { index: number, @@ -691,7 +691,6 @@ export class PolyOffestUtil1 { private m_Polyline: Polyline; private m_OffestDist: number; - private IsKeepAllCurves = false; //为true时 保留全部,不优化裁剪 constructor(pl: Polyline, offest: number) { this.m_Polyline = pl; @@ -719,7 +718,7 @@ export class PolyOffestUtil1 // c.Outline.ColorIndex = 2; // app.m_Database.ModelSpace.Append(c.Outline); // }) - console.time("trim") + // console.time("trim") cus = this.trimByContours2(cus, contours).filter(c => { if (c.IntersectWith(this.m_Polyline, IntersectOption.OnBothOperands).length !== 0) return false; @@ -728,7 +727,7 @@ export class PolyOffestUtil1 let rad2 = Math.pow(this.m_OffestDist, 2); return (dist1 - rad2 >= -1e-3 || dist2 - rad2 >= -1e-3); }); - console.timeEnd("trim") + // console.timeEnd("trim") return this.linkCurves(cus); } @@ -1072,28 +1071,55 @@ export class PolyOffestUtil1 tmpCus[tmpCus.length] = l; continue; } - let pts = l.IntersectWith(outline, IntersectOption.OnBothOperands); - // 在上面或者在外面 - if (isTargetCurOutOrOnSourceCur2(outline, l, pts)) + let interPts = l.IntersectWith(outline, IntersectOption.OnBothOperands); + let pars = interPts.map(p => l.GetParamAtPoint(p)); + let needCaclPts: Vector3[] = []; + pars.forEach(par => + { + par >= 0.02 && needCaclPts.push(l.GetPointAtParam(par - 0.01)); + par <= (l.EndParam - 0.02) && needCaclPts.push(l.GetPointAtParam(par + 0.01)); + }) + if (needCaclPts.length <= 1) + { + if (pars.length === 0) + { + needCaclPts = [l.StartPoint]; + } else + { + needCaclPts.push(l.StartPoint, l.EndPoint); + } + } + + if (IsPtsAllOutOrOnReg(outline, needCaclPts)) { tmpCus[tmpCus.length] = l; } else { - if (pts.length > 0) - { - let par = pts.map(p => l.GetParamAtPoint(p)); - let cus = l.GetSplitCurves(par); - if (cus.length > 0) - tmpCus.push(...cus.filter(cu => !equaln(cu.Length, 0, 1e-6) && !isTargetCurInOrOnSourceCur(outline, cu))); - else if (isTargetCurOutOrOnSourceCur2(outline, l, pts)) - { - console.warn('不正常情况') - tmpCus.push(l); - } - } + let cus = l.GetSplitCurves(pars); + tmpCus.push(...cus.filter(cu => !equaln(cu.Length, 0, 1e-6) && !ptInRectOrCircle(outline, cu.GetPointAtParam(0.5)))); } + + // 在上面或者在外面 + // if (isTargetCurOutOrOnSourceCur2(outline, l, interPts)) + // { + // tmpCus[tmpCus.length] = l; + + // } + // else + // { + // let pars = interPts.map(p => l.GetParamAtPoint(p)); + // let cus = l.GetSplitCurves(pars); + + // if (cus.length > 0) + // tmpCus.push(...cus.filter(cu => !equaln(cu.Length, 0, 1e-6) && !isTargetCurInOrOnSourceCur(outline, cu))); + // else if (isTargetCurOutOrOnSourceCur2(outline, l, interPts)) + // { + // console.warn('不正常情况') + // tmpCus.push(l); + // } + // } } needCutCus = tmpCus; })