예제 #1
0
파일: TestMath3D.cs 프로젝트: olesar/Altaxo
        public static void Test_GetPolylinePointsWithWestAndNorth_01()
        {
            const double maxDev = 1E-6;

            for (int caseNo = 0; caseNo < _testCases.Length; ++caseNo)
            {
                var points         = _testCases[caseNo].Item1;
                var expectedOutput = _testCases[caseNo].Item2;

                var result = PolylineMath3D.GetPolylinePointsWithWestAndNorth(points).ToArray();

                // Verify results
                Assert.AreEqual(expectedOutput.Length, result.Length);

                for (int i = 0; i < expectedOutput.Length; ++i)
                {
                    string comment = string.Format("In case no. {0}, i={1}", caseNo, i);

                    Assert.AreEqual(expectedOutput[i].Item1, result[i].Position, comment);

                    Assert.AreEqual(expectedOutput[i].Item2.X, result[i].WestVector.X, maxDev, comment);
                    Assert.AreEqual(expectedOutput[i].Item2.Y, result[i].WestVector.Y, maxDev, comment);
                    Assert.AreEqual(expectedOutput[i].Item2.Z, result[i].WestVector.Z, maxDev, comment);

                    Assert.AreEqual(expectedOutput[i].Item3.X, result[i].NorthVector.X, maxDev, comment);
                    Assert.AreEqual(expectedOutput[i].Item3.Y, result[i].NorthVector.Y, maxDev, comment);
                    Assert.AreEqual(expectedOutput[i].Item3.Z, result[i].NorthVector.Z, maxDev, comment);
                }
            }
        }
예제 #2
0
파일: TestMath3D.cs 프로젝트: olesar/Altaxo
        public static void Test_GetPolylinePointsWithWestAndNorth_02()
        {
            const double maxDev = 1E-6;
            var          rnd    = new System.Random();

            var testPoints = new PointD3D[1024];

            testPoints[0] = PointD3D.Empty;
            testPoints[1] = new PointD3D(0, 0.1, 0); // first line segment always in y direction, so that north is in z direction and west in -x direction
            for (int i = 2; i < testPoints.Length; ++i)
            {
                testPoints[i] = new PointD3D(rnd.NextDouble(), rnd.NextDouble(), rnd.NextDouble());
            }

            var result = PolylineMath3D.GetPolylinePointsWithWestAndNorth(testPoints).ToArray();

            for (int i = 1; i < result.Length; ++i)
            {
                var forwardRaw = result[i].Position - result[i - 1].Position;
                var west       = result[i].WestVector;
                var north      = result[i].NorthVector;

                Assert.AreNotEqual(forwardRaw.Length, 0); // GetPolylinePointsWithWestAndNorth should only deliver non-empty segments
                var forward = forwardRaw.Normalized;

                Assert.AreEqual(west.Length, 1, maxDev);                          // is west normalized
                Assert.AreEqual(north.Length, 1, maxDev);                         // is north normalized
                Assert.AreEqual(VectorD3D.DotProduct(west, forward), 0, maxDev);  // is west perpendicular to forward
                Assert.AreEqual(VectorD3D.DotProduct(north, forward), 0, maxDev); // is north perpendicular to forward
                Assert.AreEqual(VectorD3D.DotProduct(west, north), 0, maxDev);    // is west perpendicular to north
                var matrix = Altaxo.Geometry.Matrix4x3.NewFromBasisVectorsAndLocation(west, north, forward, PointD3D.Empty);
                Assert.AreEqual(matrix.Determinant, 1, maxDev);                   // west-north-forward are a right handed coordinate system
            }
        }
예제 #3
0
        /// <summary>
        /// Determines whether a polyline is hit.
        /// </summary>
        /// <param name="points">The points that make out the polyline.</param>
        /// <param name="thickness1">The thickness of the pen in east direction.</param>
        /// <param name="thickness2">The thickness of the pen in north direction.</param>
        /// <returns>True if the polyline is hit; otherwise false.</returns>
        public bool IsHit(IEnumerable <PointD3D> points, double thickness1, double thickness2)
        {
            var polyline = PolylineMath3D.GetPolylinePointsWithWestAndNorth(points);

            var coll = polyline.GetEnumerator();

            if (!coll.MoveNext())
            {
                return(false); // no points
            }
            double thickness1By2 = thickness1 / 2;
            double thickness2By2 = thickness2 / 2;
            var    pts           = new PointD3D[8];

            PointD3D P0 = coll.Current.Position;

            while (coll.MoveNext())
            {
                var P1 = coll.Current.Position;    // end point of current line
                var e  = coll.Current.WestVector;  // east vector
                var n  = coll.Current.NorthVector; // north vector

                pts[0] = _hitTransformation.Transform(P0 - thickness1By2 * e - thickness2By2 * n);
                pts[1] = _hitTransformation.Transform(P1 - thickness1By2 * e - thickness2By2 * n);
                pts[2] = _hitTransformation.Transform(P0 + thickness1By2 * e - thickness2By2 * n);
                pts[3] = _hitTransformation.Transform(P1 + thickness1By2 * e - thickness2By2 * n);
                pts[4] = _hitTransformation.Transform(P0 - thickness1By2 * e + thickness2By2 * n);
                pts[5] = _hitTransformation.Transform(P1 - thickness1By2 * e + thickness2By2 * n);
                pts[6] = _hitTransformation.Transform(P0 + thickness1By2 * e + thickness2By2 * n);
                pts[7] = _hitTransformation.Transform(P1 + thickness1By2 * e + thickness2By2 * n);

                foreach (var ti in RectangleD3D.GetTriangleIndices())
                {
                    if (HitTestWithAlreadyTransformedPoints(pts[ti.Item1], pts[ti.Item2], pts[ti.Item3], out var z) && z >= 0)
                    {
                        return(true);
                    }
                }

                P0 = P1; // take previous point from current point
            }

            return(false);
        }