예제 #1
0
        public IPolylineD3D ShortenedBy(RADouble marginAtStart, RADouble marginAtEnd)
        {
            if (_points.Length < 2)
            {
                return(null);
            }

            double totLength = TotalLineLength;

            double a1 = marginAtStart.IsAbsolute ? marginAtStart.Value : marginAtStart.Value * totLength;
            double a2 = marginAtEnd.IsAbsolute ? marginAtEnd.Value : marginAtEnd.Value * totLength;

            if (!((a1 + a2) < totLength))
            {
                return(null);
            }

            PointD3D?p0 = null;
            PointD3D?p1 = null;
            int      i0 = 0;
            int      i1 = 0;

            if (a1 <= 0)
            {
                p0 = PointD3D.Interpolate(_points[0], _points[1], a1 / totLength);
                i0 = 1;
            }
            else
            {
                double sum = 0, prevSum = 0;
                for (int i = 1; i < _points.Length; ++i)
                {
                    sum += (_points[i] - _points[i - 1]).Length;
                    if (!(sum < a1))
                    {
                        p0 = PointD3D.Interpolate(_points[i - 1], _points[i], (a1 - prevSum) / (sum - prevSum));
                        i0 = p0 != _points[i] ? i : i + 1;
                        break;
                    }
                    prevSum = sum;
                }
            }

            if (a2 <= 0)
            {
                p1 = PointD3D.Interpolate(_points[_points.Length - 2], _points[_points.Length - 1], 1 - a2 / totLength);
                i1 = _points.Length - 2;
            }
            else
            {
                double sum = 0, prevSum = 0;
                for (int i = _points.Length - 2; i >= 0; --i)
                {
                    sum += (_points[i] - _points[i + 1]).Length;
                    if (!(sum < a2))
                    {
                        p1 = PointD3D.Interpolate(_points[i + 1], _points[i], (a2 - prevSum) / (sum - prevSum));
                        i1 = p1 != _points[i] ? i : i - 1;
                        break;
                    }
                    prevSum = sum;
                }
            }

            if (p0.HasValue && p1.HasValue)
            {
                var plist = new List <PointD3D>
                {
                    p0.Value
                };
                for (int i = i0; i <= i1; ++i)
                {
                    plist.Add(_points[i]);
                }
                plist.Add(p1.Value);
                return(new SharpPolylineD3D(plist.ToArray()));
            }
            else
            {
                return(null);
            }
        }
예제 #2
0
파일: TestMath3D.cs 프로젝트: olesar/Altaxo
        public static void Test_GetFractionalPolyline_01()
        {
            const double maxDev  = 1E-6;
            string       comment = string.Empty;

            for (int caseNo = 0; caseNo < _testCases.Length; ++caseNo)
            {
                if (caseNo == 1 || caseNo == 2) // not with coincidenting points
                {
                    continue;
                }

                var points         = _testCases[caseNo].Item1;
                var expectedOutput = _testCases[caseNo].Item2;

                var maxEndIndex = points.Length - 1;

                for (double endIndex = 0.25; endIndex <= maxEndIndex; endIndex += 0.25)
                {
                    for (double startIndex = 0; startIndex < endIndex; startIndex += 0.25)
                    {
                        var result = PolylineMath3D.GetPolylineWithFractionalStartAndEndIndex(
                            points,
                            expectedOutput[0].Item2, expectedOutput[0].Item3, (points[1] - points[0]).Normalized, startIndex, endIndex,
                            false,
                            false,
                            new PolylinePointD3DAsClass(),
                            false,
                            false,
                            new PolylinePointD3DAsClass()).ToArray();

                        int iShift = (int)Math.Floor(startIndex);
                        for (int i = (int)Math.Ceiling(startIndex); i < (int)Math.Floor(endIndex); ++i)
                        {
                            comment = string.Format("In case no. {0}, startIndex={1}, endIndex={2}, i={3}", caseNo, startIndex, endIndex, i);

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

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

                            Assert.AreEqual(expectedOutput[i].Item3.X, result[i - iShift].NorthVector.X, maxDev, comment);
                            Assert.AreEqual(expectedOutput[i].Item3.Y, result[i - iShift].NorthVector.Y, maxDev, comment);
                            Assert.AreEqual(expectedOutput[i].Item3.Z, result[i - iShift].NorthVector.Z, maxDev, comment);
                        }

                        // start
                        int    startIndexInt      = (int)Math.Floor(startIndex);
                        double startIndexFrac     = startIndex - startIndexInt;
                        var    expectedStartPoint = startIndexFrac == 0 ? points[startIndexInt] : PointD3D.Interpolate(points[startIndexInt], points[startIndexInt + 1], startIndexFrac);
                        int    vecIndex           = startIndexFrac == 0 ? startIndexInt : startIndexInt + 1;

                        comment = string.Format("In case no. {0}, startIndex={1}, endIndex={2}", caseNo, startIndex, endIndex);

                        Assert.AreEqual(expectedStartPoint, result[0].Position, comment);

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

                        Assert.AreEqual(expectedOutput[vecIndex].Item3.X, result[0].NorthVector.X, maxDev, comment);
                        Assert.AreEqual(expectedOutput[vecIndex].Item3.Y, result[0].NorthVector.Y, maxDev, comment);
                        Assert.AreEqual(expectedOutput[vecIndex].Item3.Z, result[0].NorthVector.Z, maxDev, comment);

                        // end
                        int    endIndexInt      = (int)Math.Floor(endIndex);
                        double endIndexFrac     = endIndex - endIndexInt;
                        var    expectedEndPoint = endIndexFrac == 0 ? points[endIndexInt] : PointD3D.Interpolate(points[endIndexInt], points[endIndexInt + 1], endIndexFrac);
                        vecIndex = endIndexFrac == 0 ? endIndexInt : endIndexInt + 1;
                        var resultLast = result[result.Length - 1];

                        Assert.AreEqual(expectedEndPoint, resultLast.Position, comment);

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

                        Assert.AreEqual(expectedOutput[vecIndex].Item3.X, resultLast.NorthVector.X, maxDev, comment);
                        Assert.AreEqual(expectedOutput[vecIndex].Item3.Y, resultLast.NorthVector.Y, maxDev, comment);
                        Assert.AreEqual(expectedOutput[vecIndex].Item3.Z, resultLast.NorthVector.Z, maxDev, comment);

                        // test first returned
                    }
                }
            }
        }