CSG2d bugfix

Fixes bug in IsInside(p) test for splines if p lies on an edge of the surrounding triangle.
Do a fast check using (new) function IsCloseToTrig() instead of IsInsideTrig().
This commit is contained in:
Matthias Hochsteger 2020-11-11 15:56:56 +01:00
parent f97601bca2
commit de76069283
2 changed files with 36 additions and 1 deletions

View File

@ -402,6 +402,12 @@ bool IsInsideTrig( const array<Point<2>,3> & t, Point<2> r )
return ( (w % 2) != 0 ); return ( (w % 2) != 0 );
} }
bool IsCloseToTrig( const array<Point<2>,3> & t, Point<2> r, double eps=1e-4 )
{
r += eps * (Center(t[0], t[1], t[2])-r); // move point a bit to center of trig
return IsInsideTrig( t, r );
}
IntersectionType IntersectTrig( Point<2> p0, Point<2> p1, const array<Point<2>,3> & trig) IntersectionType IntersectTrig( Point<2> p0, Point<2> p1, const array<Point<2>,3> & trig)
{ {
@ -1612,7 +1618,7 @@ bool Loop :: IsInside( Point<2> r ) const
auto s0 = s.StartPI(); auto s0 = s.StartPI();
auto s1 = s.TangentPoint(); auto s1 = s.TangentPoint();
auto s2 = s.EndPI(); auto s2 = s.EndPI();
if(!IsInsideTrig( {s0, s1, s2} , r )) if(!IsCloseToTrig( {s0, s1, s2} , r ))
w += w_simple; w += w_simple;
else else
{ {

View File

@ -54,6 +54,35 @@ def test_trig_and_circle():
ngs.Draw(mesh) ngs.Draw(mesh)
def test_circle_plus_rect():
circle = Circle( center=(0,0), radius=1 )
rect = Rectangle( pmin=(-0.5,0.0), pmax=(0.5,0.5) )
geo = CSG2d()
geo.Add(circle+rect)
m = geo.GenerateMesh(maxh=0.2)
ngs = pytest.importorskip("ngsolve")
mesh = ngs.Mesh(m)
mesh.Curve(5)
assert ngs.Integrate(1.0, mesh) == approx(math.pi)
def test_circle_plus_rect1():
circle = Circle( center=(0,0), radius=1 )
rect = Rectangle( pmin=(-0.5,-0.5), pmax=(0.5,0.5) )
geo = CSG2d()
geo.Add(circle+rect)
m = geo.GenerateMesh(maxh=0.2)
ngs = pytest.importorskip("ngsolve")
mesh = ngs.Mesh(m)
mesh.Curve(5)
assert ngs.Integrate(1.0, mesh) == approx(math.pi)
if __name__ == "__main__": if __name__ == "__main__":
test_two_circles() test_two_circles()
test_two_edge() test_two_edge()