csg2d - fix overlap detection, test

This commit is contained in:
Matthias Hochsteger 2020-08-28 18:35:35 +02:00
parent f2b9251032
commit 2a7d6bb55e
2 changed files with 41 additions and 11 deletions

View File

@ -268,7 +268,7 @@ IntersectionType IntersectSplineSegment( const Spline & s, const Point<2> & r0,
return ClassifyNonOverlappingIntersection(alpha, beta); return ClassifyNonOverlappingIntersection(alpha, beta);
} }
IntersectionType IntersectSplineSegment1( const Spline & s, const Point<2> & r0, const Point<2> & r1, double& alpha, double& beta ) IntersectionType IntersectSplineSegment1( const Spline & s, const Point<2> & r0, const Point<2> & r1, double& alpha, double& beta, bool first=false)
{ {
Point<2> p0 = s.StartPI(); Point<2> p0 = s.StartPI();
Point<2> p1 = s.TangentPoint(); Point<2> p1 = s.TangentPoint();
@ -310,11 +310,14 @@ IntersectionType IntersectSplineSegment1( const Spline & s, const Point<2> & r0,
} }
int choice = 0; int choice = 0;
if(vtype[0]==NO_INTERSECTION && vtype[1]!=NO_INTERSECTION) if(!first)
choice = 1; {
if(vtype[0]==NO_INTERSECTION && vtype[1]!=NO_INTERSECTION)
choice = 1;
if(valpha[0] < alpha+EPSILON) if(valpha[0] < alpha+EPSILON)
choice = 1; choice = 1;
}
if(valpha[choice] < alpha+EPSILON) if(valpha[choice] < alpha+EPSILON)
return NO_INTERSECTION; return NO_INTERSECTION;
@ -342,12 +345,12 @@ bool IsOverlapping( Spline p, Spline s, double & alpha, double & beta, Intersect
// Check if s.p0 lies on p and vice versa, also check if tangents are in same direction (TODO: TEST) // Check if s.p0 lies on p and vice versa, also check if tangents are in same direction (TODO: TEST)
// If so, assume overlapping splines // If so, assume overlapping splines
// TODO: Better checks! False positives could happen here! // TODO: Better checks! False positives could happen here!
IntersectSplineSegment1( p, s.StartPI(), p_mid, lam0, alpha ); IntersectSplineSegment1( p, s.StartPI(), p_mid, lam0, alpha, true );
IntersectSplineSegment1( s, p.StartPI(), s_mid, lam1, beta ); IntersectSplineSegment1( s, p.StartPI(), s_mid, lam1, beta, true );
// Also check if midpoints lie on other spline // Also check if midpoints lie on other spline
IntersectSplineSegment1( p, s.GetPoint(0.5), p_mid, lam2, alpha_mid ); IntersectSplineSegment1( p, s.GetPoint(0.5), p_mid, lam2, alpha_mid, true );
IntersectSplineSegment1( s, p.GetPoint(0.5), s_mid, lam3, beta_mid ); IntersectSplineSegment1( s, p.GetPoint(0.5), s_mid, lam3, beta_mid, true );
auto tang0 = s.GetTangent(0.); auto tang0 = s.GetTangent(0.);
auto tang1 = p.GetTangent(alpha); auto tang1 = p.GetTangent(alpha);

View File

@ -10,24 +10,51 @@ def test_two_circles():
geo = CSG2d() geo = CSG2d()
geo.Add(s) geo.Add(s)
m = geo.GenerateMesh() m = geo.GenerateMesh()
assert m.ne > 0 assert len(m.Elements2D()) > 0
ngs = pytest.importorskip("ngsolve") ngs = pytest.importorskip("ngsolve")
mesh = ngs.Mesh(m) mesh = ngs.Mesh(m)
mesh.Curve(5) mesh.Curve(5)
assert ngs.Integrate(1.0, mesh) == approx(math.pi) assert ngs.Integrate(1.0, mesh) == approx(math.pi)
ngs.Draw(mesh)
def test_two_edge(): def test_two_edge():
s = Solid2d( [(-1,0), cp(0,1), (1,0), cp(0,2)] ) s = Solid2d( [(-1,0), cp(0,1), (1,0), cp(0,2)] )
geo = CSG2d() geo = CSG2d()
geo.Add(s) geo.Add(s)
m = geo.GenerateMesh() m = geo.GenerateMesh()
assert m.ne > 0 assert len(m.Elements2D()) > 0
ngs = pytest.importorskip("ngsolve") ngs = pytest.importorskip("ngsolve")
g = geo.GenerateSplineGeometry() g = geo.GenerateSplineGeometry()
ngs.Draw(g) ngs.Draw(g)
mesh = ngs.Mesh(m)
mesh.Curve(5)
ngs.Draw(mesh)
def test_trig_and_circle():
g = CSG2d()
trig = Solid2d( [(0,0), (1,1), (-1,1) ] ).BC("diamond")
circle = Circle( center=(0,0.101), radius=0.1).BC("circle") # TODO: Failing with center=(0,0.1)
d = trig-circle
g.Add(d)
g.Add(circle)
m = g.GenerateMesh(maxh=0.1)
assert len(m.Elements2D()) > 0
ngs = pytest.importorskip("ngsolve")
geo = g.GenerateSplineGeometry()
ngs.Draw(geo)
mesh = ngs.Mesh(m)
mesh.Curve(3)
ngs.Draw(mesh)
if __name__ == "__main__": if __name__ == "__main__":
test_two_circles() test_two_circles()
test_two_edge() test_two_edge()
test_trig_and_circle()