<commit_before>﻿using System;
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json;
using UnitClassLibrary;
using UnitClassLibrary.DistanceUnit;
using MoreLinq;
using UnitClassLibrary.DistanceUnit.DistanceTypes;

namespace GeometryClassLibrary
{
    /// <summary>
    /// A line segment is a portion of a line, whether curved or straight.
    /// </summary>
    [JsonObject(MemberSerialization.OptIn)]
    public partial class LineSegment : Vector, IEdge, IEquatable<LineSegment>, IShift<LineSegment>
    {
        #region Properties and Fields

        /// <summary>
        /// Returns this lineSegment's length (this is the same as the magnitude)
        /// </summary>
        public virtual Distance Length
        {
            get { return base.Magnitude; }
        }

        /// <summary>
        /// Returns the midpoint of this lineSegment
        /// </summary>
        public Point MidPoint
        {
            get { return EndPoints.CenterPoint(); }
        }

        public List<Point> EndPoints
        {
            get { return new List<Point>() { BasePoint, EndPoint }; }
        }

        public bool IsClosed { get { return false; } }

        public Direction InitialDirection { get { return Direction; } }
        #endregion

        #region Constructors

        /// <summary>
        /// Null Constructor
        /// </summary>
        protected LineSegment() { }

        /// <summary>
        /// Creates a Line Segment that extends from the origin to the given end point
        /// </summary>
        public LineSegment(Point passedEndPoint)
            : base(passedEndPoint)
        {
            _checkSegment();
        }

        /// <summary>
        /// Constructs a line segment that corresponds to the given vector, with the same basepoint, direction and length
        /// </summary>
        /// <param name="passedVector"></param>
        public LineSegment(Vector passedVector)
            : base(passedVector)
        {
            _checkSegment();
        }

        /// <summary>
        /// Constructs a line segment from a given start point to a given end point
        /// </summary>
        public LineSegment(Point passedBasePoint, Point passedEndPoint)
            : base(passedBasePoint, passedEndPoint)
        {
            _checkSegment();
        }
        
        /// <summary>
        /// Creates a new line segment with the given BasePoint in the same direction and magnitude as the passed Vector
        /// </summary>
        public LineSegment(Point passedBasePoint, Vector passedVector)
            : base(passedBasePoint, passedVector)
        {
            _checkSegment();
        }

        public LineSegment(Point basePoint, Direction direction, Distance magnitude)
            : base(basePoint, direction, magnitude)
        {
            _checkSegment();
        }
        public LineSegment(Direction direction, Distance magnitude)
            : base(direction, magnitude)
        {
            _checkSegment();
        }

        public LineSegment(List<Point> points) : base(points[0],points[1])
        {
            _checkSegment();
        }

        /// <summary>
        /// Copies a Linesegment
        /// </summary>
        public LineSegment(LineSegment toCopy)
            : base(toCopy.BasePoint, toCopy.Direction,toCopy.Magnitude) { }

        public LineSegment(DistanceType distanceUnit, double x1, double y1, double x2, double y2)
            : base(new Point(distanceUnit, x1, y1), new Point(distanceUnit, x2, y2)) { }

        public LineSegment(DistanceType distanceUnit, double x1, double y1, double z1, double x2, double y2, double z2)
            : base(new Point(distanceUnit, x1, y1, z1), new Point(distanceUnit, x2, y2, z2)) { }

        private void _checkSegment()
        {
            if (this.BasePoint == null || this.EndPoint == null)
            {
                throw new ArgumentNullException("BasePoint or EndPoint is null!");
            }
            if (this.BasePoint == this.EndPoint)
            {
                throw new InvalidLineSegmentException("LineSegment has no breadth!");
            }
        }
        #endregion

        #region Overloaded Operators


        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        /// <summary>
        /// Not a perfect equality operator, is only accurate up to the Distance Class's accuracy
        /// </summary>
        public static bool operator ==(LineSegment segment1, LineSegment segment2)
        {
            if ((object)segment1 == null)
            {
                if ((object)segment2 == null)
                {
                    return true;
                }
                return false;
            }
            return segment1.Equals(segment2);
        }

        /// <summary>
        /// Not a perfect inequality operator, is only accurate up to the Distance Class's accuracy
        /// </summary>
        public static bool operator !=(LineSegment segment1, LineSegment segment2)
        {
            if ((object)segment1 == null)
            {
                if ((object)segment2 == null)
                {
                    return false;
                }
                return true;
            }
            return !segment1.Equals(segment2);
        }

        /// <summary>
        /// does the same thing as ==
        /// </summary>
        public override bool Equals(object obj)
        {
            if (obj == null || !(obj is LineSegment))
            {
                return false;
            }
           
            LineSegment comparableSegment = (LineSegment)obj;

            // if the two points' x and y are equal, returns true
            bool pointsAreEqual = comparableSegment.BasePoint.Equals(this.BasePoint) && comparableSegment.EndPoint.Equals(this.EndPoint);
            bool pointsAreReverse = comparableSegment.BasePoint.Equals(this.EndPoint) && comparableSegment.EndPoint.Equals(this.BasePoint);

            return pointsAreEqual || pointsAreReverse;  
        }

        /// <summary>
        /// does the same thing as ==
        /// </summary>
        public bool Equals(LineSegment segment)
        {
            if (segment == null)
            {
                return false;
            }

            // if the two points' x and y are equal, returns true
            bool pointsAreEqual = segment.BasePoint.Equals(this.BasePoint) && segment.EndPoint.Equals(this.EndPoint);
            bool pointsAreReverse = segment.BasePoint.Equals(this.EndPoint) && segment.EndPoint.Equals(this.BasePoint);

            return pointsAreEqual || pointsAreReverse;  
        }

        /// <summary>
        /// returns the line segment as a string
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return string.Format("BasePoint= {0}, EndPoint= {1}, Length={2}", this.BasePoint.ToString(), this.EndPoint.ToString(), this.Length.ToString());
        }
        #endregion

        #region Methods

        /// <summary>
        /// Checks if this Vector intersects the given line and returns the point if it does or null otherwise
        /// </summary>
        /// <param name="passedLine">The line to check if this intersects with</param>
        /// <returns>returns the intersection point of the two lines or null if they do not</returns>
        public override Point IntersectWithLine(Line passedLine)
        {
            Point intersect = new Line(this).IntersectWithLine(passedLine);

            if (!ReferenceEquals(intersect, null) && intersect.IsOnLineSegment(this))
            {
                return intersect;
            }
            return null;
        }

        public virtual Point IntersectWithPlane(Plane plane)
        {
            return plane.IntersectWithSegment(this);
        }

        /// <summary>
        /// Checks if this LineSegment intersects with the given LineSegment and returns the point of intersection
        /// </summary>
        public Point IntersectWithSegment(LineSegment segment)
        {
            if (this.BasePoint.IsBaseOrEndPointOf(segment))
            {
                return this.BasePoint;
            }
            else if (this.EndPoint.IsBaseOrEndPointOf(segment))
            {
                return this.EndPoint;
            }
            Point potentialIntersect = base.IntersectWithLine(segment);

            if (potentialIntersect != null && potentialIntersect.IsOnLineSegment(segment) && potentialIntersect.IsOnLineSegment(this))<commit_msg>Fixed behavior of IntersectWithLine method<commit_after>﻿using System;
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json;
using UnitClassLibrary;
using UnitClassLibrary.DistanceUnit;
using MoreLinq;
using UnitClassLibrary.DistanceUnit.DistanceTypes;

namespace GeometryClassLibrary
{
    /// <summary>
    /// A line segment is a portion of a line, whether curved or straight.
    /// </summary>
    [JsonObject(MemberSerialization.OptIn)]
    public partial class LineSegment : Vector, IEdge, IEquatable<LineSegment>, IShift<LineSegment>
    {
        #region Properties and Fields

        /// <summary>
        /// Returns this lineSegment's length (this is the same as the magnitude)
        /// </summary>
        public virtual Distance Length
        {
            get { return base.Magnitude; }
        }

        /// <summary>
        /// Returns the midpoint of this lineSegment
        /// </summary>
        public Point MidPoint
        {
            get { return EndPoints.CenterPoint(); }
        }

        public List<Point> EndPoints
        {
            get { return new List<Point>() { BasePoint, EndPoint }; }
        }

        public bool IsClosed { get { return false; } }

        public Direction InitialDirection { get { return Direction; } }
        #endregion

        #region Constructors

        /// <summary>
        /// Null Constructor
        /// </summary>
        protected LineSegment() { }

        /// <summary>
        /// Creates a Line Segment that extends from the origin to the given end point
        /// </summary>
        public LineSegment(Point passedEndPoint)
            : base(passedEndPoint)
        {
            _checkSegment();
        }

        /// <summary>
        /// Constructs a line segment that corresponds to the given vector, with the same basepoint, direction and length
        /// </summary>
        /// <param name="passedVector"></param>
        public LineSegment(Vector passedVector)
            : base(passedVector)
        {
            _checkSegment();
        }

        /// <summary>
        /// Constructs a line segment from a given start point to a given end point
        /// </summary>
        public LineSegment(Point passedBasePoint, Point passedEndPoint)
            : base(passedBasePoint, passedEndPoint)
        {
            _checkSegment();
        }
        
        /// <summary>
        /// Creates a new line segment with the given BasePoint in the same direction and magnitude as the passed Vector
        /// </summary>
        public LineSegment(Point passedBasePoint, Vector passedVector)
            : base(passedBasePoint, passedVector)
        {
            _checkSegment();
        }

        public LineSegment(Point basePoint, Direction direction, Distance magnitude)
            : base(basePoint, direction, magnitude)
        {
            _checkSegment();
        }
        public LineSegment(Direction direction, Distance magnitude)
            : base(direction, magnitude)
        {
            _checkSegment();
        }

        public LineSegment(List<Point> points) : base(points[0],points[1])
        {
            _checkSegment();
        }

        /// <summary>
        /// Copies a Linesegment
        /// </summary>
        public LineSegment(LineSegment toCopy)
            : base(toCopy.BasePoint, toCopy.Direction,toCopy.Magnitude) { }

        public LineSegment(DistanceType distanceUnit, double x1, double y1, double x2, double y2)
            : base(new Point(distanceUnit, x1, y1), new Point(distanceUnit, x2, y2)) { }

        public LineSegment(DistanceType distanceUnit, double x1, double y1, double z1, double x2, double y2, double z2)
            : base(new Point(distanceUnit, x1, y1, z1), new Point(distanceUnit, x2, y2, z2)) { }

        private void _checkSegment()
        {
            if (this.BasePoint == null || this.EndPoint == null)
            {
                throw new ArgumentNullException("BasePoint or EndPoint is null!");
            }
            if (this.BasePoint == this.EndPoint)
            {
                throw new InvalidLineSegmentException("LineSegment has no breadth!");
            }
        }
        #endregion

        #region Overloaded Operators


        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        /// <summary>
        /// Not a perfect equality operator, is only accurate up to the Distance Class's accuracy
        /// </summary>
        public static bool operator ==(LineSegment segment1, LineSegment segment2)
        {
            if ((object)segment1 == null)
            {
                if ((object)segment2 == null)
                {
                    return true;
                }
                return false;
            }
            return segment1.Equals(segment2);
        }

        /// <summary>
        /// Not a perfect inequality operator, is only accurate up to the Distance Class's accuracy
        /// </summary>
        public static bool operator !=(LineSegment segment1, LineSegment segment2)
        {
            if ((object)segment1 == null)
            {
                if ((object)segment2 == null)
                {
                    return false;
                }
                return true;
            }
            return !segment1.Equals(segment2);
        }

        /// <summary>
        /// does the same thing as ==
        /// </summary>
        public override bool Equals(object obj)
        {
            if (obj == null || !(obj is LineSegment))
            {
                return false;
            }
           
            LineSegment comparableSegment = (LineSegment)obj;

            // if the two points' x and y are equal, returns true
            bool pointsAreEqual = comparableSegment.BasePoint.Equals(this.BasePoint) && comparableSegment.EndPoint.Equals(this.EndPoint);
            bool pointsAreReverse = comparableSegment.BasePoint.Equals(this.EndPoint) && comparableSegment.EndPoint.Equals(this.BasePoint);

            return pointsAreEqual || pointsAreReverse;  
        }

        /// <summary>
        /// does the same thing as ==
        /// </summary>
        public bool Equals(LineSegment segment)
        {
            if (segment == null)
            {
                return false;
            }

            // if the two points' x and y are equal, returns true
            bool pointsAreEqual = segment.BasePoint.Equals(this.BasePoint) && segment.EndPoint.Equals(this.EndPoint);
            bool pointsAreReverse = segment.BasePoint.Equals(this.EndPoint) && segment.EndPoint.Equals(this.BasePoint);

            return pointsAreEqual || pointsAreReverse;  
        }

        /// <summary>
        /// returns the line segment as a string
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return string.Format("BasePoint= {0}, EndPoint= {1}, Length={2}", this.BasePoint.ToString(), this.EndPoint.ToString(), this.Length.ToString());
        }
        #endregion

        #region Methods

        /// <summary>
        /// Checks if this Vector intersects the given line and returns the point if it does or null otherwise
        /// </summary>
        /// <param name="line">The line to check if this intersects with</param>
        /// <returns>returns the intersection point of the two lines or null if they do not</returns>
        public override Point IntersectWithLine(Line line)
        {
            Point intersect = new Line(this).IntersectWithLine(new Line(line));

            if (!ReferenceEquals(intersect, null) && intersect.IsOnLineSegment(this))
            {
                return intersect;
            }
            return null;
        }

        public virtual Point IntersectWithPlane(Plane plane)
        {
            return plane.IntersectWithSegment(this);
        }

        /// <summary>
        /// Checks if this LineSegment intersects with the given LineSegment and returns the point of intersection
        /// </summary>
        public Point IntersectWithSegment(LineSegment segment)
        {
            if (this.BasePoint.IsBaseOrEndPointOf(segment))
            {
                return this.BasePoint;
            }
            else if (this.EndPoint.IsBaseOrEndPointOf(segment))
            {
                return this.EndPoint;
            }
            Point potentialIntersect = base.IntersectWithLine(segment);

            if (potentialIntersect != null && potentialIntersect.IsOnLineSegment(segment) && potentialIntersect.IsOnLineSegment(this))
{'fraction_non_alphanumeric': 0.09533220949834331, 'fraction_numerical': 0.004301575306632564, 'mean_word_length': 1.742984693877551, 'pattern_counts': {'":': 0, '<': 93, '<?xml version=': 0, '>': 93, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5623900', 'n_tokens_mistral': 4286, 'n_tokens_neox': 4129, 'n_words': 1220}