public void Rotation_Constructor_Matrix()
        {
            Vector vector1 = new Vector(Point.MakePointWithInches(2, 3, -6), Direction.Out, new Distance(1, Inches));
            Vector vector2 = new Vector(Point.MakePointWithInches(-5, 3, 7));

            //A very randomish axis
            Line testAxis = vector1.CrossProduct(vector2).Translate(Point.MakePointWithInches(3, -9, 10));

            Angle angle = new Angle(new Radian(), -173);

            Rotation rotation = new Rotation(testAxis, angle);
            Rotation fromMatrixConstructor = Rotation.RotationFromMatrix(rotation.Matrix);

            (fromMatrixConstructor.RotationAngle == angle.ProperAngle).Should().BeTrue();
            (fromMatrixConstructor.AxisOfRotation == testAxis).Should().BeTrue();
        }
 public static bool AreAllCoplanar(this List<Point> points)
 {
     Vector whatTheNormalShouldBe = null;
     for (int i = 0; i < points.Count; i++)
     {
         for (int j = i + 1; j < points.Count(); j++)
         {
             Vector vector1 = new Vector(points[i], points[j]);
             for (int k = j + 1; k < points.Count(); k++)
             {
                 Vector vector2 = new Vector(points[i], points[k]);
                 if (whatTheNormalShouldBe == null || whatTheNormalShouldBe.Magnitude == Distance.ZeroDistance)
                 {
                     whatTheNormalShouldBe = vector1.CrossProduct(vector2);
                 }
                 if (!whatTheNormalShouldBe.IsPerpendicularTo(vector2))
                 {
                     return false;
                 }
             }
         }
     }
     return true;
 }
        public void Vector_CrossProduct()
        {
            Vector xAxis = new Vector(Point.Origin, Direction.Right, new Distance(1, Inches));
            Vector yAxis = new Vector(Point.Origin, new Direction(new Angle(90, Degrees)), new Distance(1, Inches));

            Vector result = xAxis.CrossProduct(yAxis);
            Vector expected = new Vector(Point.Origin, new Direction(Angle.ZeroAngle, Angle.ZeroAngle), new Distance(1, Inches));

            result.Should().Be(expected);

            Vector resultParallel = xAxis.CrossProduct(xAxis);
            (resultParallel.Magnitude == ZeroDistance).Should().BeTrue();
        }
        private static void _removeInteriorPoints(Point initial, List<Point> pointsInOrder)
        {
            //First we compute what the normal actually is
            Vector last = new Vector(pointsInOrder[pointsInOrder.Count - 1], initial);
            Vector first = new Vector(initial, pointsInOrder[0]);
            Vector normal = last.CrossProduct(first);
            
            //Now we use a nested loop to allow us to actually edit the list we're looping through
            //The top level allows us to loop atleast as many times as we need to edit.
            //The inner loop restarts whenever we need to remove a point, but we keep track of where are index was
            //the flag tracks when we exited the inner loop normally or because we needed to remove an item
            //if we exited normally we're done
            int numberOfIterations = pointsInOrder.Count;
            int startingIndex = -1;
            for (int j = 0; j < numberOfIterations; j++)
            {
                bool flag = false;
                Point point1, point3, point2 = null;
                for (int i = startingIndex; i + 1 < pointsInOrder.Count; i++)
                {
                    if (i == -1)
                    {
                        point1 = initial;
                    }
                    point1 = pointsInOrder[i];
                    point2 = pointsInOrder[i + 1];
                    point3 = pointsInOrder[i + 2];

                    Vector vector1 = new Vector(point1, point2);
                    Vector vector2 = new Vector(point2, point3);
                    Vector shouldBeNormal = vector1.CrossProduct(vector2);

                    if (shouldBeNormal.Magnitude == Distance.ZeroDistance || !shouldBeNormal.HasSameDirectionAs(normal))
                    {
                        flag = true;
                        startingIndex = i;
                        break;
                    }
                }
                if (flag)
                {
                    pointsInOrder.Remove(point2);
                }
                else
                {
                    break;
                }
            }
        }
        // Returns a normalVector of the planeregion.
        // or the zero vector, if the planereg has no sides.
        protected Line _getNormalLine()
        {
            if (this.Edges.Count() > 2)
            {
                Vector vector1 = new Vector(_Edges.OrderBy(s => s.BasePoint.X).ThenBy(s => s.BasePoint.Y).ThenBy(s => s.BasePoint.Z).First());
               // Vector vector2 = new Vector(_Edges.First(s => s.BasePoint == vector1.EndPoint));
                Vector vector2 = null;
                for (int i = 0; i < Edges.Count; i++)
                {
                    if (Edges[i].BasePoint == vector1.EndPoint)
                    {
                        vector2=new Vector(Edges[i]);
                    }
                }

                var normal = vector1.CrossProduct(vector2);
                
                return new Line(_Edges[0].BasePoint, normal.Direction);
            }
            else
            {
                IEdge nonSegment;
                if (!(Edges[0] is LineSegment))
                {
                    nonSegment = Edges[0];
                }
                else if (!(Edges[1] is LineSegment))
                {
                    nonSegment = Edges[0];
                }
                else throw new Exception("Not Allowed.");
                var otherVertex = this.Vertices.First(v => v != nonSegment.BasePoint);
                var normalDirection = nonSegment.InitialDirection.CrossProduct(new LineSegment(nonSegment.BasePoint, otherVertex).Direction);
               return new Line(nonSegment.BasePoint, normalDirection);
            }
        }