优化点在多段线内部的算法,使算法更健壮,避免圆弧切线问题.

pull/68/head
ChenX 6 years ago
parent 91dc5f8a01
commit 32f8807a59

@ -1,12 +1,9 @@
import { Vector2, Vector3 } from 'three';
import { angle, equal, equaln, greater } from '../Geometry/GeUtils';
import { angle, 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';
import { Contour } from './Contour';
/**
* ,.
@ -73,33 +70,72 @@ export function IsPointInPolyLine(pl: Polyline, pt: Vector3): boolean
for (let i = 0; i < pl.EndParam; i++)
{
let cu = pl.GetCurveAtIndex(i);
let inpts = cu.IntersectWith(insLine, IntersectOption.ExtendArg);
if (equaln(pl.GetBuilgeAt(i), 0))//直线
{
let sp = pl.GetPointAtParam(i);
let ep = pl.GetPointAtParam(i + 1);
//点位于线上面
if (pt.y > Math.max(sp.y, ep.y))
continue;
//线垂直Y轴
let derX = ep.x - sp.x;
if (equaln(derX, 0))
continue;
for (let pti of inpts)
//起点
if (equaln(sp.x, pt.x))
{
if (pti.y < pt.y)
if (sp.y > pt.y && derX < 0) crossings++;
continue;
}
//终点
if (equaln(ep.x, pt.x))
{
if (ep.y > pt.y && derX > 0) crossings++;
continue;
}
if (equal(pti, cu.StartPoint))
//快速求交,只验证有没有交点
let [x1, x2] = sp.x > ep.x ? [ep.x, sp.x] : [sp.x, ep.x];
if (pt.x > x1 && pt.x < x2)
{
let der = cu.GetFistDeriv(0);
if (equaln(der.x, 0) && cu instanceof Arc)
der = cu.GetFistDeriv(0.1);
if (der.x < -1e-4) //左边+ 右边0
let derY = ep.y - sp.y;
let k = derY / derX;
if ((pt.x - sp.x) * k + sp.y > pt.y)
crossings++;
}
else if (equal(pti, cu.EndPoint))
}
else //圆弧
{
let der = cu.GetFistDeriv(1);
if (equaln(der.x, 0) && cu instanceof Arc)
der = cu.GetFistDeriv(0.9);
if (der.x > 1e-4) //左边+ 右边0
crossings++;
let arc = pl.GetCurveAtIndex(i);
let sp = arc.StartPoint;
let ep = arc.EndPoint;
//当点和起点或者终点和点相切时
if (equaln(sp.x, pt.x) && sp.y > pt.y)
{
let der = arc.GetFistDeriv(0);
if (equaln(der.x, 0))
{
if (ep.x - sp.x < 0) crossings++;
continue;
}
else
}
if (equaln(ep.x, pt.x) && ep.y > pt.y)
{
let der = arc.GetFistDeriv(1);
if (equaln(der.x, 0))
{
let der = cu.GetFistDeriv(pti);
if (ep.x - sp.x > 0) crossings++;
continue;
}
}
for (let pti of arc.IntersectWith(insLine, IntersectOption.ExtendArg))
{
if (pti.y < pt.y)
continue;
let der = arc.GetFistDeriv(pti);
if (!equaln(der.x, 0)) //相切.
crossings++;
}

Loading…
Cancel
Save