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); } } }
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 } }
/// <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); }