public void Point_MinusOperatorStandardTest()
        {
            Distance xDistance1 = new Distance(new Millimeter(), 5);
            Distance yDistance1 = new Distance(new Millimeter(), 5);
            Distance zDistance1 = new Distance(new Millimeter(), 5);

            Distance xDistance2 = new Distance(new Millimeter(), 5);
            Distance yDistance2 = new Distance(new Millimeter(), 5);
            Distance zDistance2 = new Distance(new Millimeter(), 5);

            Distance xDistance3 = new Distance(new Millimeter(), -10);
            Distance yDistance3 = new Distance(new Millimeter(), -10);
            Distance zDistance3 = new Distance(new Millimeter(), -10);

            Point p1 = new Point(xDistance1, yDistance1, zDistance1);
            Point p2 = new Point(xDistance2, yDistance2, zDistance2);
            Point p3 = new Point(xDistance3, yDistance3, zDistance3);

            Point cumulativePoint = (p1 - p2 - p3);
            cumulativePoint.X.Should().Be(new Distance(new Millimeter(), 10));
            cumulativePoint.Y.Should().Be(new Distance(new Millimeter(), 10));
            cumulativePoint.Z.Should().Be(new Distance(new Millimeter(), 10));


        }
 private static Polygon _makeRectangle(Distance length, Distance width, Point basePoint = null)
 {
     var vector1 = new Vector(Direction.Right, length);
     var vector2 = new Vector(Direction.Up, width);
     
     var rectangle = Parallelogram(vector1, vector2, basePoint);
     return rectangle;
 }
 public void RightTriangle_PointConstructorTest()
 {
     // Build right triangle with line segments
     Point rt_cornerOne = new Point(Point.MakePointWithInches(2, 1));
     Point rt_cornerTwo = new Point(Point.MakePointWithInches(2, 4));
     Point rt_cornerThree = new Point(Point.MakePointWithInches(4, 1));
     List<Point> rt_sides = new List<Point>() { rt_cornerOne, rt_cornerTwo, rt_cornerThree };
     RightTriangle rt = new RightTriangle(rt_sides);
 }
        public void Point_2DConstructorTest()
        {
            Distance xDistance = new Distance(new Millimeter(), 5);
            Distance yDistance = new Distance(new Millimeter(), 10);

            Point p = new Point(xDistance, yDistance);

            p.X.Should().Be(new Distance(new Millimeter(), 5));
            p.Y.Should().Be(new Distance(new Millimeter(), 10));
            p.Z.Should().Be(new Distance(new Millimeter(), 0));
        }
        private static Polyhedron _makeSolid(Distance length, Distance width, Distance height, Point basePoint = null)
        {
            if (basePoint == null)
            {
                basePoint = Point.Origin;
            }
            Distance zero = Distance.ZeroDistance;

            Vector vector1 = new Vector(new Point(zero, width, zero));
            Vector vector2 = new Vector(new Point(length, zero, zero));
            Vector vector3 = new Vector(new Point(zero, zero, height));

            var solid = MakeParallelepiped(vector1, vector2, vector3, basePoint);
            return solid;
        }
 /// <summary>
 /// Creates a rectangular prism with the given Distances in the x,y,z directions
 /// </summary>
 public RectangularPrism(Distance length, Distance width, Distance height, Point basePoint = null) : base(_makeSolid(length, width, height, basePoint)) { }
 /// <summary>
 /// Constructs the rectangular prism between the two passed points and the given point as opposite corners.
 /// </summary>
 public RectangularPrism(Point oppositeCorner, Point basePoint = null) : this(oppositeCorner.X, oppositeCorner.Y, oppositeCorner.Z, basePoint) { }
 /// <summary>
 /// Creates a Translation with offsets in each direction represented by the point
 /// </summary>param>
 
 public Translation(Point point)
 {
     this.Point = point;
 }
        private LegoBlock createBlockInGivenCoordinateSystem(Distance xDimension, Distance yDimension, Distance zDimension, CoordinateSystem blocksCoordinateSystem)
        {
            LegoBlock toReturn = new LegoBlock();

            //make our geometry
            Point basePoint = Point.Origin;
            Point topLeftPoint = new Point(Distance.ZeroDistance, yDimension, Distance.ZeroDistance);
            Point bottomRightPoint = new Point(xDimension, Distance.ZeroDistance, Distance.ZeroDistance);
            Point topRightPoint = new Point(xDimension, yDimension, Distance.ZeroDistance);

            Point backBasePoint = new Point(Distance.ZeroDistance, Distance.ZeroDistance, zDimension);
            Point backTopLeftPoint = new Point(Distance.ZeroDistance, yDimension, zDimension);
            Point backBottomRightPoint = new Point(xDimension, Distance.ZeroDistance, zDimension);
            Point backTopRightPoint = new Point(xDimension, yDimension, zDimension);

            List<Polygon> planes = new List<Polygon>();
            planes.Add(new Polygon(new List<Point> { basePoint, topLeftPoint, topRightPoint, bottomRightPoint }));
            planes.Add(new Polygon(new List<Point> { backBasePoint, backTopLeftPoint, backTopRightPoint, backBottomRightPoint }));
            planes.Add(new Polygon(new List<Point> { topLeftPoint, topRightPoint, backTopRightPoint, backTopLeftPoint }));
            planes.Add(new Polygon(new List<Point> { basePoint, bottomRightPoint, backBottomRightPoint, backBasePoint }));
            planes.Add(new Polygon(new List<Point> { basePoint, topLeftPoint, backTopLeftPoint, backBasePoint }));
            planes.Add(new Polygon(new List<Point> { bottomRightPoint, topRightPoint, backTopRightPoint, backBottomRightPoint }));

            toReturn.Geometry = new Polyhedron(planes);

            //now figure out is base coordinate system relative to the world and store it
            toReturn.BlockSystem = blocksCoordinateSystem.FindThisSystemRelativeToWorldSystemCurrentlyRelativeToPassedSystem(CURRENT_COORDINATE_SYSTEM);

            //now move it so it is in ouur current coordinate system
            toReturn.Geometry = toReturn.Geometry.Shift(blocksCoordinateSystem.ShiftFromThisTo());

            //then return it
            return toReturn;
        }
 /// <summary>
 /// given a list of edges, and a vertex, this returns all the edges that use the vertex as a base or end point
 /// NoteL this returns copies of those edges, and reorients them so that they use the vertex as a basepoint
 /// </summary>
 /// <param name="segmentList"></param>
 /// <param name="vertex"></param>
 /// <returns></returns>
 public static List<LineSegment> SegmentsAdjacentTo(this List<LineSegment> segmentList, Point vertex)
 {
     List<LineSegment> segments = new List<LineSegment>();
     foreach(LineSegment segment in segmentList)
     {
         if (segment.BasePoint == vertex)
         {
             segments.Add(new LineSegment(segment));
         }
         else if (segment.EndPoint == vertex)
         {
             segments.Add(segment.Reverse());
         }
     }
     return segments;
 }
 /// <summary>
 /// Finds all points that are points adjacent to this point via one of these linesegments
 /// </summary>
 /// <param name="edgeList"></param>
 /// <param name="vertex"></param>
 /// <returns></returns>
 public static List<Point> VerticesAdjacentTo(this List<LineSegment> edgeList, Point vertex)
 {
     List<Point> adjacentVertices = new List<Point>();
     foreach(LineSegment segment in edgeList)
     {
         if (vertex == segment.BasePoint)
         {
             adjacentVertices.Add(segment.EndPoint);
         }
         else if (vertex == segment.EndPoint)
         {
             adjacentVertices.Add(segment.BasePoint);
         }
     }
     return adjacentVertices;
 }
 /// <summary>
 /// Creates a local coordinate system that is only translated from the World Coordinates.
 /// </summary>
 public CoordinateSystem(Point passedTranslationToOrigin)
 {
     this.ShiftFromThisToWorld = new Shift(passedTranslationToOrigin);
 }
        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="passedOrigin">The origin point of this coordinate system in reference to the world coordinate system</param>
        //public CoordinateSystem(Plane planeContainingTwoOfTheAxes, Vector axisInPassedPlaneToUseAsBase,
        //    Enums.Axis whichAxisIsPassed = Enums.Axis.X, Enums.AxisPlanes whichAxisPlaneIsPassed = Enums.AxisPlanes.XYPlane)
        //{

        //    //make sure the passed vector is in our plane
        //    if (!planeContainingTwoOfTheAxes.Contains(axisInPassedPlaneToUseAsBase))
        //    {
        //        throw new ArgumentOutOfRangeException("the passed axis was not in the plane");
        //    }

        //    Vector xAxis = new Vector(Point.Origin);
        //    Vector yAxis = new Vector(Point.Origin);
        //    Vector zAxis = new Vector(Point.Origin);

        //    //Vector normalAxis = new Vector(axisInPassedPlaneToUseAsBase.BasePoint, planeContainingTwoOfTheAxes.NormalVector.Direction, new Distance(new Inch(), 1));

        //    //Vector otherAxis;

        //    switch (whichAxisPlaneIsPassed)
        //    {
        //        case Enums.AxisPlanes.XYPlane:
        //            zAxis = new Vector(axisInPassedPlaneToUseAsBase.BasePoint, planeContainingTwoOfTheAxes.NormalVector.Direction, new Distance(new Inch(), 1));
        //            switch (whichAxisIsPassed)
        //            {
        //                //if its the x we were given the one we calculate is the y, so we want it 90 degrees (to the left)
        //                case Enums.Axis.X:
        //                    xAxis = axisInPassedPlaneToUseAsBase;
        //                    yAxis = zAxis.CrossProduct(xAxis);
        //                    //otherAxis = axisInPassedPlaneToUseAsBase.Rotate(new Rotation(planeContainingTwoOfTheAxes.NormalVector, Angle.RightAngle);
        //                    break;
        //                //if its the y we were the the y axis and we need to calculate the x which will be -90 degrees (to the right)
        //                case Enums.Axis.Y:
        //                    yAxis = axisInPassedPlaneToUseAsBase;
        //                    xAxis = yAxis.CrossProduct(zAxis);
        //                    //otherAxis = axisInPassedPlaneToUseAsBase.Rotate(new Rotation(planeContainingTwoOfTheAxes.NormalVector, -1 * Angle.RightAngle);
        //                    break;
        //                //the axis must be in the plane we were passed
        //                case Axis.Z:
        //                    throw new ArgumentOutOfRangeException("the passed axis type was not in the plane type");
        //            }
        //            break;
        //        case Enums.AxisPlanes.XZPlane:
        //            yAxis = new Vector(axisInPassedPlaneToUseAsBase.BasePoint, planeContainingTwoOfTheAxes.NormalVector.Direction, new Distance(new Inch(), 1));
        //            switch (whichAxisIsPassed)
        //            {
        //                //if its the x we were passed then we need to calculate z, which will be -90 degrees (to the right)
        //                case Enums.Axis.X:
        //                    xAxis = axisInPassedPlaneToUseAsBase;
        //                    zAxis = xAxis.CrossProduct(yAxis);
        //                    //otherAxis = axisInPassedPlaneToUseAsBase.Rotate(new Rotation(planeContainingTwoOfTheAxes.NormalVector, -1 * Angle.RightAngle);
        //                    break;
        //                //the axis must be in the plane we were passed
        //                case Enums.Axis.Y:
        //                    throw new ArgumentOutOfRangeException("the passed axis type was not in the plane type");
        //                //if its the z we were passed then we need to calculate x, which will be 90 degrees (to the left)
        //                case Axis.Z:
        //                    zAxis = axisInPassedPlaneToUseAsBase;
        //                    xAxis = yAxis.CrossProduct(zAxis);
        //                    //otherAxis = axisInPassedPlaneToUseAsBase.Rotate(new Rotation(planeContainingTwoOfTheAxes.NormalVector, Angle.RightAngle);
        //                    break;
        //            }
        //            break;
        //        case Enums.AxisPlanes.YZPlane:
        //            xAxis = new Vector(axisInPassedPlaneToUseAsBase.BasePoint, planeContainingTwoOfTheAxes.NormalVector.Direction, new Distance(new Inch(), 1));
        //            switch (whichAxisIsPassed)
        //            {
        //                //the axis must be in the plane we were passed
        //                case Enums.Axis.X:
        //                    throw new ArgumentOutOfRangeException("the passed axis type was not in the plane type");
        //                //if it is the Y axis then we need to find the z, which is 90 degrees (to the left)
        //                case Enums.Axis.Y:
        //                    yAxis = axisInPassedPlaneToUseAsBase;
        //                    zAxis = xAxis.CrossProduct(yAxis);
        //                    //otherAxis = axisInPassedPlaneToUseAsBase.Rotate(new Rotation(planeContainingTwoOfTheAxes.NormalVector, Angle.RightAngle);
        //                    break;
        //                //if it is the Z axis then we need to find the y, which is -90 degrees (to the right)
        //                case Axis.Z:
        //                    zAxis = axisInPassedPlaneToUseAsBase;
        //                    yAxis = zAxis.CrossProduct(xAxis);
        //                    //otherAxis = axisInPassedPlaneToUseAsBase.Rotate(new Rotation(planeContainingTwoOfTheAxes.NormalVector, -1 * Angle.RightAngle);
        //                    break;
        //            }
        //            break;
        //    }

        //    //we found our axes, now we can determine the angles from them
        //    //Since we rotate in the order Z, X, then Y, we must find the angles in the reverse order
        //    //i.e. y first, then x then z

        //    //if we find line up the z axis in the YZ plane with the y rotation, then we can rotate it around the x axis to make the z axes line up
        //    //and then we can z rotate to make the x and y coincide with the origins

        //    //first make them into unitvectors to simplify the calculations
        //    xAxis = xAxis.Direction*Inch;
        //    yAxis = yAxis.Direction*Inch;
        //    zAxis = zAxis.Direction*Inch;

        //    //now first find out the amount we need to rotate around the y axis to line up z in the yz plane

        //    //First project the z axis onto the xz plane
        //    Line projectedZAxis = ((Line)zAxis).ProjectOntoPlane(new Plane(Line.XAxis, Line.ZAxis));

        //    //then use the projected Line to find out how far we need to rotate in the Y direction to line up the z axes in the YZplane
        //    Angle angleBetweenCurrentZAndYZPlane = projectedZAxis.Direction.Theta;

        //    //if the projection is in the negative x direction we need to rotate negitively(clockwise) instead of positivly
        //    if (projectedZAxis.Direction.XComponent > 0)
        //    {
        //        angleBetweenCurrentZAndYZPlane = angleBetweenCurrentZAndYZPlane.Negate();
        //    }

        //    //http://www.vitutor.com/geometry/distance/line_plane.html
        //    //we can simplify the equation as this since it is unit vectors
        //    //sin(angle to plane) = z * planeNormal (which is the x axis by definition)
        //    //Distance dotProductOfZAndNormal = zAxis * Line.XAxis.UnitVector(new Inch());
        //    //Angle angleBetweenCurrentZAndYZPlane = new Angle(new Radian(), Math.Asin(dotProductOfZAndNormal.ValueInInches));

        //    //now rotate the axis (we only need to do z and x since we are done with y now)
        //    xAxis = xAxis.Rotate(new Rotation(Line.YAxis, angleBetweenCurrentZAndYZPlane));
        //    zAxis = zAxis.Rotate(new Rotation(Line.YAxis, angleBetweenCurrentZAndYZPlane));

        //    //now find out how much we need to rotate it in the x direction to line up z in the xz plane (meaning now z will be aligned with the world z)
        //    Angle angleBetweenZAndZAxis = zAxis.Direction.Theta;

        //    //now we need to rotate the x axis so we can line it up (the y and z we are done with)
        //    //if its negative we need to rotate it clockwise (negative) instead of ccw (positive)
        //    if (zAxis.Direction.YComponent < 0)
        //    {
        //        angleBetweenZAndZAxis = angleBetweenZAndZAxis.Negate();
        //    }

        //    //finally find out the z rotation needed to line up the x axis with the xz plane (this also forces the y to be lined up)
        //    xAxis = xAxis.Rotate(new Rotation(Line.XAxis, angleBetweenZAndZAxis));
        //    Angle angleBetweenXAndXAxis = xAxis.Direction.Phi;

        //    //now we know all our angles, but we have to take the negative of them because we were transforming back to
        //    //the origin and we store the tranform from the origin
        //    var _xAxisRotationAngle = angleBetweenZAndZAxis.Negate();
        //    var _yAxisRotationAngle = angleBetweenCurrentZAndYZPlane.Negate();
        //    var _zAxisRotationAngle = angleBetweenXAndXAxis.Negate();

        //    var rotationX = new Rotation(Line.XAxis, _xAxisRotationAngle);
        //    var rotationY = new Rotation(Line.YAxis, _yAxisRotationAngle);
        //    var rotationZ = new Rotation(Line.ZAxis, _zAxisRotationAngle);
        //    this.ShiftFromThisToWorld = new Shift(new List<Rotation>() { rotationX, rotationY, rotationZ }, axisInPassedPlaneToUseAsBase.BasePoint);
        //}

        /// <summary>
        /// Creates a new coordinate system with the given origin point and with the given rotations.
        /// The inputs are extrinsic angle, i.e. about the global axes
        /// </summary>
        /// <param name="passedTranslationToOrigin">The origin point of this coordinate system in reference to the world coordinate system</param>
        /// <param name="passedXAxisRotation">The rotation around the world coordinate system's X axis to rotate around to get to this
        /// coordinate system</param>
        /// <param name="passedYAxisRotation">The rotation around the world coordinate system's Y axis to rotate around to get to this
        /// coordinate system</param>
        /// <param name="passedZAxisRotation">The rotation around the world coordinate system's Z axis to rotate around to get to this
        /// coordinate system</param>
        public CoordinateSystem(Point translationToOrigin, Angle xAxisRotationAngle,
            Angle yAxisRotationAngle, Angle zAxisRotationAngle)
        {
            var rotationX = new Rotation(Line.XAxis, xAxisRotationAngle);
            var rotationY = new Rotation(Line.YAxis, yAxisRotationAngle);
            var rotationZ = new Rotation(Line.ZAxis, zAxisRotationAngle);
            this.ShiftFromThisToWorld = new Shift(new List<Rotation>() { rotationX, rotationY, rotationZ }, translationToOrigin);
        }
 /// <summary>
 /// Creates a Rectangle in the XY Plane, with one corner at the origin, and the specified length, width.
 /// </summary>
 /// <param name="length"></param>
 /// <param name="width"></param>
 public Rectangle(Distance length, Distance width, Point basePoint = null) 
     : base(_makeRectangle(length, width))
 {
     this.Length = length.AbsoluteValue();
     this.Width = width.AbsoluteValue();
 }
 public Parallelogram(KeyValuePair<Vector, Vector> pair, Point basePoint = null)
     : this(pair.Key, pair.Value, basePoint) { }
 public Parallelogram(Vector vector1, Vector vector2, Point basePoint = null)
     : base(Parallelogram(vector1, vector2, basePoint)) { }