예제 #1
0
        private bool IsInside(TriangleMesh meshA, TriangleMesh meshB)
        {
            var boxA = meshA.Bounds;

            var aBTri = meshB.Triangles[0];

            aBTri = meshB.CreateOuterTriangle(aBTri, negativeOffset);

            var center      = aBTri.Center.Vector;
            var rayPositive = new Ray(center, Axis.X, AxisDirection.Positive);
            var rayNegative = new Ray(center, Axis.X, AxisDirection.Negative);
            var aBTriBoxExtendedPositive = aBTri.Bounds.ExtendInDirection(boxA, Axis.X, true);
            var aBTriBoxExtendedNegative = aBTri.Bounds.ExtendInDirection(boxA, Axis.X, false);

            var isInsideP = IntersectionCount(meshA, aBTriBoxExtendedPositive, rayPositive);
            var isInsideN = IntersectionCount(meshA, aBTriBoxExtendedNegative, rayNegative);

            if (isInsideP != isInsideN)
            {
                throw new InvalidOperationException();
            }

            return(isInsideP);
        }
예제 #2
0
        public bool TouchWithoutInnerOuterTest(TriangleMesh meshA, TriangleMesh meshB, double positiveOffset, double negativeOffset)
        {
            this.meshA = meshA;
            this.meshB = meshB;
            treeA      = meshA.RTreeRoot;
            treeB      = meshB.RTreeRoot;

            var input = new List <List <ITreeItem> >();

            input.Add(new List <ITreeItem>()
            {
                treeA.Root, treeB.Root
            });

            currentPositivOffset  = positiveOffset;
            currentNegativeOffset = negativeOffset;

            outerIntersectFound = false;

            var result = OverlapWithOffset(input);

            //Console.WriteLine(intersectingCall);
            return(result);
        }
예제 #3
0
 public bool SouthOfRelaxed(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(DirectionRelaxed(meshA, meshB, Axis.X, false));
 }
예제 #4
0
 public bool NorthOfStrict(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(DirectionStrict(meshA, meshB, Axis.X, true));
 }
예제 #5
0
 public bool NorthOfRelaxed(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(DirectionRelaxed(meshA, meshB, Axis.X, true));
 }
예제 #6
0
 public bool WestOfStrict(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(DirectionStrict(meshA, meshB, Axis.Y, false));
 }
예제 #7
0
        public Tuple <TriangleMesh, TriangleMesh, double> Distance(TriangleMesh meshA, TriangleMesh meshB)
        {
            treeA = meshA.RTreeRoot;
            treeB = meshB.RTreeRoot;

            var rootBoxA = treeA.Bounds;
            var rootBoxB = treeB.Bounds;

            var minDistGloabal = Box.BoxDistanceMinMax(rootBoxA, rootBoxB);

            if (minDistGloabal.Min > settings.Distance.GlobalThreshold)
            {
                return(new Tuple <TriangleMesh, TriangleMesh, double>(meshA, meshB, settings.Distance.GlobalThreshold));
            }

            var outList = new List <Tuple <ITreeItem, ITreeItem> >();
            var inList  = new List <List <ITreeItem> > {
                new List <ITreeItem> {
                    treeA.RootNode, treeB.RootNode
                }
            };

            //var stopW = new Stopwatch();
            //stopW.Start("RTree");
            DistanceCandidates(inList, outList, null);
            var minDist = Distance(outList);

            //stopW.Stop();


            //stopW.Start("BruteForce");
            //var minDistBF = double.MaxValue;
            //foreach (var triA in meshA.Triangles)
            //{
            //    foreach (var triB in meshB.Triangles)
            //    {
            //        var distBF = triA.MinSqrDistance(triB);
            //        if (distBF < minDistBF)
            //            minDistBF = distBF;
            //    }
            //}
            //stopW.Stop();

            //minDistBF = Math.Sqrt(minDistBF);
            //Console.WriteLine("BF: " + minDistBF + " , Tree: " + Math.Sqrt(minDist));

            return(new Tuple <TriangleMesh, TriangleMesh, double>(meshA, meshB, Math.Sqrt(minDist)));
        }
예제 #8
0
 public bool BelowOfRelaxed(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(DirectionRelaxed(meshA, meshB, Axis.Z, false));
 }
예제 #9
0
 public bool AboveOfRelaxed(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(DirectionRelaxed(meshA, meshB, Axis.Z, true));
 }
예제 #10
0
        public bool EqualRTree(TriangleMesh meshA, TriangleMesh meshB, out double meanDist, out int numberOfUnmatched)
        {
            var box1 = meshA.Bounds;
            var box2 = meshB.Bounds;


            var threshold    = settings.Equal.GlobalThreshold;
            var thresholdSqr = threshold * threshold;

            numberOfUnmatched = 0;

            //todo
            if (!box1.Offset(threshold).Intersects(box2)) // BBs weiter als threshold weg
            {
                meanDist = 0;
                return(false);
            }

            var distances = new List <double>();

            //iteriere über dreiecke von A

            foreach (var triangle1 in meshA.Triangles)
            {
                //such andere dreiecke innerhalb threshold
                var tree1BoxExtended         = triangle1.Bounds.Offset(threshold);
                var tree2TrianglesCandidates = meshB.RTreeRoot.FindOverlap(tree1BoxExtended).ToList();

                //iteriere über sample points von A
                foreach (var sample in triangle1.SamplingPoints)
                {
                    var distancesOverTris2 = new List <double>();
                    foreach (var triangle2 in tree2TrianglesCandidates)
                    {
                        // sammle alle sqr dists über alle triangle candidaten von B
                        distancesOverTris2.Add(triangle2.MinSqrDistance(sample));
                    }

                    //minimale distance über triangle candidaten von B
                    var distanceOT2Min = distancesOverTris2.Minimum();


                    //ggf keine triangle candidaten von B
                    var distanceOT2Count = distancesOverTris2.Count;

                    //wenn keine candidaten von B oder minimale Distanz größer als Threshold
                    //auf thresshold setzen
                    if (distanceOT2Count == 0 || distanceOT2Min > thresholdSqr)
                    {
                        numberOfUnmatched++;
                    }
                    else
                    {
                        //minimale Distanz für Sampling über B Candidaten
                        distances.Add(Math.Sqrt(distanceOT2Min));
                    }

                    if (numberOfUnmatched > meshA.SampleCount / 10)
                    {
                        meanDist = 0;
                        return(false);
                    }
                }
            }

            meanDist = distances.Mean();
            return(true);
        }
예제 #11
0
        public bool EqualBruteForceOri(TriangleMesh meshA, TriangleMesh meshB, out double meanDist)
        {
            var box1 = meshA.Bounds;
            var box2 = meshB.Bounds;


            //todo
            if (!box1.Offset(settings.Equal.GlobalThreshold).Intersects(box2)) // BBs weiter als threshold weg
            {
                meanDist = 0;

                return(false);
            }

            var triAToTrisBwithMinDist = new List <Tuple <Triangle, List <Tuple <Triangle, double> > > >();

            foreach (var triangle1 in meshA.Triangles)
            {
                var tupleList = new List <Tuple <Triangle, double> >();
                foreach (var triangle2 in meshB.Triangles)
                {
                    var minSqrDist = triangle1.MinSqrDistance(triangle2);
                    tupleList.Add(new Tuple <Triangle, double>(triangle2, minSqrDist));
                }
                triAToTrisBwithMinDist.Add(new Tuple <Triangle, List <Tuple <Triangle, double> > >(triangle1, tupleList));
            }

            var triAWithTriBsSampleCandidates = new List <Tuple <Triangle, List <Triangle> > >();

            foreach (var tuple in triAToTrisBwithMinDist)
            {
                var triA = tuple.Item1;
                var triBwithDistanceList = tuple.Item2;

                var minSqrDist = triBwithDistanceList.Min(t => t.Item2);

                var minSqrBTris = triBwithDistanceList.Where(t => t.Item2 == minSqrDist).ToList();

                var maxSqrDistFromCandidates = minSqrBTris.Select(t => t.Item1.MaxSqrDistance(triA)).Max();

                var triBCandidates = triBwithDistanceList.Where(t => t.Item2 < maxSqrDistFromCandidates);

                triAWithTriBsSampleCandidates.Add(new Tuple <Triangle, List <Triangle> >(triA, triBCandidates.Select(t => t.Item1).ToList()));
            }


            var distances = new List <double>();

            //iteriere über dreiecke von A
            foreach (var tuple in triAWithTriBsSampleCandidates)
            {
                var triA = tuple.Item1;

                //sampling auf A dreieck
                pointSampler.DistributePoints(triA, settings.Equal.SamplePerSquareMeter);

                var treeBTrianglesCandidates = tuple.Item2;

                //iteriere über sample points von A
                foreach (var sample in triA.SamplingPoints)
                {
                    var distancesOverTris2 = new List <double>();
                    foreach (var triangle2 in treeBTrianglesCandidates)
                    {
                        // sammle alle sqr dists über alle triangle candidaten von B
                        distancesOverTris2.Add(triangle2.MinSqrDistance(sample));
                    }

                    //minimale distance über triangle candidaten von B
                    var distanceOT2Min = distancesOverTris2.Minimum();

                    //minimale Distanz für Sampling über B Candidaten
                    distances.Add(distanceOT2Min);
                }
            }

            meanDist = Math.Sqrt(distances.Mean());
            return(true);
        }
예제 #12
0
 public bool Contain(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(Contain(meshA, meshB, settings.Contain.NegativeOffset));
 }
예제 #13
0
 public bool Cover(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(Cover(meshA, meshB, settings.Touch.PositiveOffset, settings.Touch.NegativeOffset));
 }
예제 #14
0
 public bool Overlap(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(Overlap(meshA, meshB, settings.Overlap.NegativeOffset));
 }
예제 #15
0
 public bool SouthOfStrict(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(DirectionStrict(meshA, meshB, Axis.X, false));
 }
예제 #16
0
        private bool EmitRays(Triangle triangle2, List <Triangle> candidateTriangles1, TriangleMesh mesh1, Axis axis, bool positiveDirection)
        {
            var positiveOffset = settings.Direction.PositiveOffset;

            foreach (var samplePoint in triangle2.SamplingPoints)
            {
                var direction = positiveDirection ? AxisDirection.Positive : AxisDirection.Negative;
                var ray       = new Ray(samplePoint, axis, direction);

                var doesIntersect = false;
                foreach (var candidateTriangle in candidateTriangles1)
                {
                    var outerTri = mesh1.CreateOuterTriangle(candidateTriangle, positiveOffset);
                    doesIntersect = rayTriangleIntersector.TestStrict(ray, outerTri);
                    if (doesIntersect)
                    {
                        break;
                    }
                }

                if (!doesIntersect)
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #17
0
 public bool EastOfRelaxed(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(DirectionRelaxed(meshA, meshB, Axis.Y, true));
 }
예제 #18
0
 public bool AboveOfStrict(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(DirectionStrict(meshA, meshB, Axis.Z, true));
 }
예제 #19
0
 public bool EastOfStrict(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(DirectionStrict(meshA, meshB, Axis.Y, true));
 }
예제 #20
0
 public bool BelowOfStrict(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(DirectionStrict(meshA, meshB, Axis.Z, false));
 }
예제 #21
0
 public bool WestOfRelaxed(TriangleMesh meshA, TriangleMesh meshB)
 {
     return(DirectionRelaxed(meshA, meshB, Axis.Y, false));
 }