Ejemplo n.º 1
0
        public LineSegment2D(Point2D a, Point2D b)
        {
            PointPair = new Point2D[2];

            PointPair[0] = a;
            PointPair[1] = b;
        }
Ejemplo n.º 2
0
        public Point2DCollection(Point2D[] points, int capacity)
        {
            Capacity = capacity;
            CurrentCount = points.Length;

            if (Capacity < CurrentCount)
            {
                throw (new CollectionCapacityException());
            }

            Points = points;
        }
Ejemplo n.º 3
0
        public Polygon2DLinkMaker(Polygon2D polygon, int a, int b)
            : base(polygon)
        {
            if (!polygon.isRegular)
            {
                throw (new ArgumentException());
            }

            FirstPoint = polygon.GetPoint(a);
            LastPoint = polygon.GetPoint(b);
            LinkDivisers = new Point2DCollection();
            //Partitions = new Polygon2DCollection();
            //Partitions.Add(polygon);
        }
        public Point2D ConvertPoint2DFromString(string point)
        {
            Point2D point2D = new Point2D();
            StringBuilder stringBuilder = new StringBuilder(point);

            stringBuilder.Remove(0, 1);
            stringBuilder.Remove(stringBuilder.Length - 1, 1);

            string[] s = stringBuilder.ToString().Split(',');

            point2D.X = double.Parse(s[0]);
            point2D.Y = double.Parse(s[1]);

            return point2D;
        }
Ejemplo n.º 5
0
 public Point2D(Point2D p)
     : base(p)
 {
 }
Ejemplo n.º 6
0
        public Point2D GetClosestPointOnLineSegment(Point2D a, Point2D b)
        {
            Point2D p = this.ParametrizationToLineSegment(a, b);

            return WeightedAverage(a, b, p.X);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Make a parametrization to a line segment specified by two other points.
        /// </summary>
        /// <param name="a">the first point of the line segment.</param>
        /// <param name="b">the second point of the line segment.</param>
        /// <returns></returns>
        protected Point2D ParametrizationToLineSegment(Point2D a, Point2D b)
        {
            if (a == b)
            {
                throw new ArgumentException("The points defining the line are not distinct.");
            }
            else
            {
                Vector2D AB = b - a;
                Vector2D AP = this - a;
                Point2D p = new Point2D();

                // x = AB * AP/|AB|^2 = |AP|cos<AB,AP>/|AB|
                p.X = Vector2D.Dot(AB, AP) / AB.SquaredLength;

                // y = |AB X AP|/|AB|^2 = |AP|sin<AB,AP>/|AB|
                p.Y = Vector2D.Determinant(AB, AP) / AB.SquaredLength;
                return p;
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Get the parametres of the points on line segment. (between 0 t0 1)
        /// </summary>
        /// <param name="point">the point.</param>
        /// <returns>the parametre of the point on line segment.</returns>
        public double GetPosition(Point2D point)
        {
            if (point == FirstPoint)
            {
                return 0;
            }
            else if (point == LastPoint)
            {
                return 1;
            }
            else
            {
                Vector2D v1 = point - FirstPoint;
                Vector2D v2 = this.ToVector();
                double d = Vector2D.Determinant(v1, v2);

                if (d < ZeroTolerance)
                {
                    return v1.Length / v2.Length;
                }
                else if (d >= ZeroTolerance)
                {
                    return double.PositiveInfinity;
                }
                else
                {
                    return double.NegativeInfinity;
                }
            }
        }
Ejemplo n.º 9
0
        private PointF[] GhostTriangleToPoints(int i)
        {
            Point2D[] points = new Point2D[3];

            points[0] = this.polygon.GetPoint(this.ghostTriangles[i].A);
            points[1] = this.polygon.GetPoint(this.ghostTriangles[i].B);
            points[2] = this.polygon.GetPoint(this.ghostTriangles[i].C);

            PointF[] pointfs = new PointF[3];

            pointfs[0] = new PointF((float)(points[0].X), (float)(points[0].Y));
            pointfs[1] = new PointF((float)(points[1].X), (float)(points[1].Y));
            pointfs[2] = new PointF((float)(points[2].X), (float)(points[2].Y));

            return pointfs;
        }
Ejemplo n.º 10
0
        protected override void OnMouseMove(MouseEventArgs e)
        {
            Point2D point = new Point2D(e.X, e.Y - 30);
            Polygon2DAdorner polygonAdorner = null;
            Partition part = OnPart(point);

            this.statusBarPanel1.Text = this.GetPolygonStatus(point);
            if (part == Partition.Left)
            {
                polygonAdorner = this.LeftPolygon;
            }
            else
            {
                point.X -= this.ClientSize.Width / 2;
                polygonAdorner = this.RightPolygon;
            }

            int i = StatusController.CatchPoint;

            if (i != -1)
            {
                this.Cursor = System.Windows.Forms.Cursors.Default;

                if (StatusController.availablePartition == part)
                {
                    Polygon2DEditor pe = new Polygon2DEditor(polygonAdorner.polygon);

                    pe.SetPoint(point, i);

                    StatusController.canRestart = false;

                }

                this.Invalidate();
            }
            else
            {
                i = polygonAdorner.HitTest(point);
                if (i == -1)
                {
                    this.Cursor = System.Windows.Forms.Cursors.Default;
                }
                else
                {
                    this.Cursor = System.Windows.Forms.Cursors.Cross;
                }
                this.statusBarPanel2.Text =point.ToString() + "    " + "Hint Index : " + i.ToString() + " ";
            }

            if (StatusController.isZoomView)
            {
                PointF midPoint;
                if (part == Partition.Left)
                {
                    midPoint = new PointF(this.ClientSize.Width / 4, this.ClientSize.Height / 2);

                }
                else
                {
                    midPoint = new PointF(3 * this.ClientSize.Width / 4, this.ClientSize.Height / 2);
                }

                if (e.X < midPoint.X && e.Y  < midPoint.Y)
                {
                    this.Cursor = System.Windows.Forms.Cursors.PanNW;
                }
                else if (e.X > midPoint.X && e.Y  < midPoint.Y)
                {
                    this.Cursor = System.Windows.Forms.Cursors.PanNE;
                }
                else if (e.X < midPoint.X && e.Y > midPoint.Y)
                {
                    this.Cursor = System.Windows.Forms.Cursors.PanSW;
                }
                else
                {
                    this.Cursor = System.Windows.Forms.Cursors.PanSE;
                }
            }
        }
Ejemplo n.º 11
0
        private string GetPolygonStatus(Point2D point)
        {
            StringBuilder status = new StringBuilder();
            Polygon2D polygon = null;

            status.Append("Polygon:");

            if (this.OnPart(point) == Partition.Left)
            {
                status.Append("Left  ");
                polygon = this.FirstPolygon;
            }
            else
            {
                status.Append("Right  ");
                polygon = this.SecondPolygon;
            }

            status.Append(polygon.VertexCount.ToString());
            status.Append("(" + polygon.InnerPointCount.ToString() + ")");
            status.Append(" points");

            if (polygon.isRegular)
            {
                status.Append(" Regular");
            }
            else
            {
                status.Append(" Not regular");
            }

            if (polygon.isSimple)
            {
                status.Append(" Simple");
            }
            else
            {
                status.Append(" Complex");
            }

            if (polygon.isConvex)
            {
                status.Append(" Convex ");
            }
            else
            {
                status.Append(" Concave ");
            }

            status.Append(polygon.PointDirection.ToString());

            if (StatusController.isZoomView)
            {
                int r = 0;

                if (this.OnPart(point) == Partition.Left)
                {
                    r = (int)(100 / StatusController.LeftZoom.ratio);
                }
                else
                {
                    r = (int)(100 / StatusController.RightZoom.ratio);
                }

                status.Append(" ");
                status.Append(r.ToString());
                status.Append("% Zoom");
            }

            return status.ToString();
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Add an inner point to the polygon.
 /// </summary>
 /// <param name="point">the new inner point.</param>
 public void AddInnerPoint(Point2D point)
 {
     Polygon.AddInner(point);
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Add new point to the polygon.
 /// </summary>
 /// <param name="point">new point.</param>
 public void AddPoint(Point2D point)
 {
     Polygon.Add(point);
 }
Ejemplo n.º 14
0
        private bool isRegular(int index, Point2D point)
        {
            WebNode Router = this.webNodes[index];

            while (Router != null)
            {
                if (this.GetArea(Router.firstIndex, Router.secondIndex, point.X, point.Y) < GhostWeb.AreaTolerance)
                {
                    return false;
                }
                Router = Router.Next;
            }
            return true;
        }
Ejemplo n.º 15
0
 /// <summary>
 /// Reset a point of the polygon.
 /// </summary>
 /// <param name="point">the new point.</param>
 /// <param name="i">the point index.</param>
 public void SetPoint(Point2D point, int i)
 {
     Polygon.SetPoint(point, i);
 }
Ejemplo n.º 16
0
        public void Write(Polygon2D Polygon)
        {
            this.SetReverse(Polygon);

            XmlTextWriter xmlWriter = new XmlTextWriter(Path, Encoding.UTF8);

            xmlWriter.WriteStartDocument(true);
                xmlWriter.WriteStartElement("pn", "Polygon", "urn:Microsoft.VS.Akira.Triangulations");
                    xmlWriter.WriteStartElement("pn:Coordinate");
                        xmlWriter.WriteStartAttribute("", "type", "");
                            xmlWriter.WriteString("Reversed");
                        xmlWriter.WriteEndAttribute();
                        xmlWriter.WriteStartAttribute("", "top", "");
                            xmlWriter.WriteString(this.Reverse.ToString());
                        xmlWriter.WriteEndAttribute();
                        xmlWriter.WriteStartAttribute("", "margin", "");
                            xmlWriter.WriteString(XWFParser.Margin.ToString());
                        xmlWriter.WriteEndAttribute();
                    xmlWriter.WriteEndElement();
                    xmlWriter.WriteStartElement("pn:Vertices");
                        xmlWriter.WriteStartAttribute("","count","");
                        xmlWriter.WriteString(Polygon.VertexCount.ToString());
                        xmlWriter.WriteEndAttribute();

            for(int i = 0; i < Polygon.VertexCount; i++)
            {
                Point2D point = new Point2D(Polygon.GetPoint(i));
                point.Y = this.Reverse + XWFParser.Margin - point.Y;

                xmlWriter.WriteStartElement("pn:Vertex");
                xmlWriter.WriteStartAttribute("","index","");
                xmlWriter.WriteString(i.ToString());
                xmlWriter.WriteEndAttribute();
                xmlWriter.WriteStartAttribute("","x","");
                xmlWriter.WriteString(point.X.ToString());
                xmlWriter.WriteEndAttribute();
                xmlWriter.WriteStartAttribute("","y","");
                xmlWriter.WriteString(point.Y.ToString());
                xmlWriter.WriteEndAttribute();
                xmlWriter.WriteStartAttribute("","z","");
                xmlWriter.WriteString("0");
                xmlWriter.WriteEndAttribute();

                xmlWriter.WriteEndElement();
            }

                    xmlWriter.WriteEndElement();

                    xmlWriter.WriteStartElement("pn:Edges");

            for (int i = 0; i < Polygon.VertexCount; i++)
            {
                xmlWriter.WriteStartElement("pn:Edge");
                xmlWriter.WriteStartAttribute("","from","");
                xmlWriter.WriteString(i.ToString());
                xmlWriter.WriteEndAttribute();
                xmlWriter.WriteStartAttribute("","to","");
                xmlWriter.WriteString(((i+1) % Polygon.VertexCount).ToString());
                xmlWriter.WriteEndAttribute();
                xmlWriter.WriteEndElement();
            }

                    xmlWriter.WriteEndElement();
                xmlWriter.WriteEndElement();
            xmlWriter.WriteEndDocument();

            xmlWriter.Close();
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Get the intersect point of the two lines.
        /// </summary>
        /// <param name="line">the other line.</param>
        /// <returns>the point.</returns>
        public Point2D Intersects(Line2D line)
        {
            if (this.GetPosition(line) != Position.Intersect)
            {
                //throw (new ArgumentException("The two lines cannot Intersects!"));
                return new Point2D(double.PositiveInfinity, double.PositiveInfinity);
            }

            Vector v1 = null;
            Vector v2 = null;

            if (Math.Abs(this.A) > Math.Abs(line.A))
            {
                v1 = new Vector(this.vector);
                v2 = new Vector(line.vector);
            }
            else
            {
                v1 = new Vector(line.vector);
                v2 = new Vector(this.vector);
            }

            Vector v3 = new Vector(v1);

            v1 = Vector.Multiply(v2[0] / v1[0], v1);
            v1 = Vector.Subtract(v1, v2);
            v1 = Vector.Multiply(1/v1[1], v1);

            Point2D point = new Point2D(new Line2D(v3).GetX(-v1[2]), -v1[2]);

            if (!this.Contains(point) || !line.Contains(point))
            {
                throw (new ArgumentException());
            }

            return point;
        }
Ejemplo n.º 18
0
        public void Write(Polygon2D polygon)
        {
            Stream stream = new FileStream(this.Path, FileMode.Create, FileAccess.Write, FileShare.None);

            string str = "# WFMESH2";

            stream.Write(this.GetBytes(str), 0, str.Length);
            stream.WriteByte((byte)'\r');
            stream.WriteByte((byte)'\n');

            str = "# Created by Triangulator";

            stream.Write(this.GetBytes(str), 0, str.Length);
            stream.WriteByte((byte)'\r');
            stream.WriteByte((byte)'\n');

            str = "# Vertices";

            stream.Write(this.GetBytes(str), 0, str.Length);
            stream.WriteByte((byte)'\r');
            stream.WriteByte((byte)'\n');

            this.SetReverse(polygon);

            for (int i = 0; i < polygon.VertexCount; i++)
            {
                Point2D point = new Point2D(polygon.GetPoint(i));
                point.Y = this.Reverse + WFParser.Margin - point.Y;

                str = point.X.ToString() + " " + point.Y.ToString() + " " + "0.00" + " " + i.ToString();

                stream.Write(this.GetBytes(str), 0, str.Length);
                stream.WriteByte((byte)'\r');
                stream.WriteByte((byte)'\n');
            }

            stream.WriteByte((byte)'\r');
            stream.WriteByte((byte)'\n');

            str = "# Edges";
            stream.Write(this.GetBytes(str), 0, str.Length);
            stream.WriteByte((byte)'\r');
            stream.WriteByte((byte)'\n');

            for (int i = 0; i < polygon.VertexCount - 1; i++)
            {
                str = i.ToString() + " " + (i + 1).ToString();

                stream.Write(this.GetBytes(str), 0, str.Length);
                stream.WriteByte((byte)'\r');
                stream.WriteByte((byte)'\n');
            }

            str = (polygon.VertexCount - 1).ToString() + " 0";

            stream.Write(this.GetBytes(str), 0, str.Length);
            stream.WriteByte((byte)'\r');
            stream.WriteByte((byte)'\n');

            stream.Close();
        }
Ejemplo n.º 19
0
 private Partition OnPart(Point2D point)
 {
     if (point.X < this.ClientSize.Width / 2)
     {
         return Partition.Left;
     }
     else
     {
         return Partition.Right;
     }
 }
Ejemplo n.º 20
0
 /// <summary>
 /// Add new point to the polygon.
 /// </summary>
 /// <param name="point">new point.</param>
 /// <param name="i">point index.</param>
 public void AddPoint(Point2D point, int i)
 {
     Polygon.Add(point, i);
 }
Ejemplo n.º 21
0
        protected override void OnMouseDown(MouseEventArgs e)
        {
            Point2D point = new Point2D(e.X, e.Y - 30);

            if (StatusController.availablePartition != OnPart(point))
            {
                StatusController.availablePartition = OnPart(point);
                this.Invalidate();
                return;
            }

            if (StatusController.isZoomView)
            {
                if (e.Button == MouseButtons.Left)
                {
                    this.MoveTimer.Start();
                    if (OnPart(point) == Partition.Left)
                    {

                        PointF midPoint = new PointF(this.ClientSize.Width / 4, this.ClientSize.Height / 2);

                        if (e.X < midPoint.X)
                        {
                            StatusController.LeftZoom.Offset.X += (float)StatusController.LeftZoom.ratio;
                        }
                        else
                        {
                            StatusController.LeftZoom.Offset.X -= (float)StatusController.LeftZoom.ratio;
                        }
                        if (e.Y < midPoint.Y)
                        {
                            StatusController.LeftZoom.Offset.Y += (float)StatusController.LeftZoom.ratio;
                        }
                        else
                        {
                            StatusController.LeftZoom.Offset.Y -= (float)StatusController.LeftZoom.ratio;
                        }

                    }
                    else
                    {
                        PointF midPoint = new PointF(3 * this.ClientSize.Width / 4, this.ClientSize.Height / 2);

                        if (e.X < midPoint.X)
                        {
                            StatusController.RightZoom.Offset.X += (float)StatusController.RightZoom.ratio;
                        }
                        else
                        {
                            StatusController.RightZoom.Offset.X -= (float)StatusController.RightZoom.ratio;
                        }

                        if (e.Y < midPoint.Y)
                        {
                            StatusController.RightZoom.Offset.Y += (float)StatusController.RightZoom.ratio;
                        }
                        else
                        {
                            StatusController.RightZoom.Offset.Y -= (float)StatusController.RightZoom.ratio;
                        }
                    }
                }
                else if (e.Button == MouseButtons.Right)
                {
                    this.MoveTimer.Stop();
                    StatusController.LeftZoom.ratio = 1.0;
                    StatusController.LeftZoom.Offset = new PointF(0.0F, -30.0F);

                    StatusController.RightZoom.ratio = 1.0;
                    StatusController.RightZoom.Offset = new PointF(0.0F, -30.0F);
                }
                this.Invalidate();
                return;
            }

            Polygon2DAdorner polygonAdorner = null;

            if (OnPart(point) == Partition.Left)
            {
                polygonAdorner = this.LeftPolygon;
            }
            else
            {
                point.X -= this.ClientSize.Width / 2;
                polygonAdorner = this.RightPolygon;
            }

            if (e.Button == MouseButtons.Left)
            {

                int i = polygonAdorner.HitTest(point);

                if (i == -1 && StatusController.canAddPoint)
                {
                    if (StatusController.availablePartition == Partition.Left)
                    {
                        Polygon2DEditor pe = new Polygon2DEditor(FirstPolygon);

                        pe.AddPoint(point);

                        StatusController.canRestart = false;
                    }
                    else
                    {
                        Polygon2DEditor pe = new Polygon2DEditor(this.SecondPolygon);

                        pe.AddPoint(new Point2D(point));

                        StatusController.canRestart = false;
                    }
                }

                else
                {
                    StatusController.CatchPoint = i;
                }
            }
            else
            {
                int i = polygonAdorner.HitTest(point);

                if (i != -1)
                {
                    if (StatusController.availablePartition == Partition.Left)
                    {
                        Polygon2DEditor pe = new Polygon2DEditor(this.FirstPolygon);

                        pe.RemovePoint(i);

                        StatusController.canRestart = false;
                    }
                    else
                    {
                        Polygon2DEditor pe = new Polygon2DEditor(this.SecondPolygon);

                        pe.RemovePoint(i);

                        StatusController.canRestart = false;
                    }
                }
            }
            this.Invalidate();
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Whether the point is on the line.
        /// </summary>
        /// <param name="point">the point.</param>
        /// <returns>true if is on the line.</returns>
        public bool isOnLine(Point2D point)
        {
            if (point == FirstPoint || point == LastPoint)
            {
                return true;
            }
            else
            {
                Vector2D v1 = point - FirstPoint;
                Vector2D v2 = LastPoint - point;

                return Vector2D.Determinant(v1, v2) < ZeroTolerance;
            }
        }
Ejemplo n.º 23
0
        protected override void OnMouseUp(MouseEventArgs e)
        {
            Point2D point = new Point2D(e.X, e.Y);

            StatusController.CatchPoint = -1;

            this.statusBarPanel1.Text = this.GetPolygonStatus(point);
            this.MoveTimer.Stop();
        }
Ejemplo n.º 24
0
 /// <summary>
 /// Wether the line contains the point.
 /// </summary>
 /// <param name="point">the point.</param>
 /// <returns>true if contains.</returns>
 public bool Contains(Point2D point)
 {
     double d = point.X * this.A + point.Y * this.B + this.C;
     if (d < Line2D.ZeroTolerance)
     {
         return true;
     }
     else
     {
         return false;
     }
 }
Ejemplo n.º 25
0
        /// <summary>
        /// Whether the three points is on a line.
        /// </summary>
        /// <param name="a">the first point.</param>
        /// <param name="b">the second point.</param>
        /// <param name="c">the third point.</param>
        /// <returns>true if is on a line.</returns>
        public static bool isOnLine(Point2D a, Point2D b, Point2D c)
        {
            LineSegment2D line = new LineSegment2D(a, b);

            return line.isOnLine(c);
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Computes the shortest distance from this point to the line defined by the parameters.
        /// Points <paramref name="a"/> and <paramref name="b"/> must be distinct.
        /// </summary>
        /// <param name="a">The first point defining the line.</param>
        /// <param name="b">The second point defining the line.</param>
        /// <returns>The distance from this point to the line defined by the parameters.</returns>
        /// <exception cref="ArgumentException">
        ///	The points defining the line are not distinct.
        /// </exception>
        public double DistanceToLine(Point2D a, Point2D b)
        {
            if (a == b)
            {
                throw new ArgumentException("The points defining the line are not distinct.");
            }
            else
            {
                double distanceAB = Distance(a, b);

                // dist(P, Line(A,B) = |det(AB,AP)| / d(A,B).
                return Math.Abs(((b.X - a.X) * (this.Y - a.Y) - (this.X - a.X) * (b.Y - a.Y)) / distanceAB);
            }
        }
Ejemplo n.º 27
0
 /// <summary>
 /// Compares two points using lexicographic order.
 /// </summary>
 /// <param name="a">The first point.</param>
 /// <param name="b">The second point.</param>
 /// <returns>-1 if <paramref name="a"/> is less than <paramref name="b"/>,
 /// 0 if <paramref name="a"/> equals <paramref name="b"/>,
 /// and 1 if <paramref name="a"/> is greater than <paramref name="b"/>.</returns>
 public static int Compare(Point2D a, Point2D b)
 {
     if (a.X > b.X || (a.X == b.X && a.Y > b.Y))
     {
         return 1;
     }
     else if (a.X < b.X || (a.X == b.X && a.Y < b.Y))
     {
         return -1;
     }
     else
     {
         return 0;
     }
 }
Ejemplo n.º 28
0
        /*private void SetOffset(ref PointF[] points, PointF point)
        {
            for (int i = 0; i < points.Length; i++)
            {
                points[i].X -= point.X;
                points[i].Y -= point.Y;
            }
        }

        private void SetOffset(ref PointF a, PointF b)
        {
            a.X -= b.X;
            a.Y -= b.Y;
        }*/
        public int HitTest(Point2D point)
        {
            for (int i = 0; i < this.polygon.VertexCount; i++)
            {
                Point2D p = this.polygon.GetPoint(i);

                if (Math.Abs(point.X - p.X) <= 3 && Math.Abs(point.Y - p.Y) <= 3)
                {
                    return i;
                }
            }

            return -1;
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Whether the line segment contains the point and the point is not on the terminal.
        /// </summary>
        /// <param name="point">the point.</param>
        /// <returns>true if truly contains.</returns>
        public bool TrulyContains(Point2D point)
        {
            Vector2D v1 = point - FirstPoint;
            Vector2D v2 = LastPoint - point;
            double d1 = v1 * v2;
            double d2 = Vector2D.Determinant(v1, v2);

            if ((d1 > ZeroTolerance) && Math.Abs(d2) < ZeroTolerance)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Returns the weighted average of two points.
        /// </summary>
        /// <param name="a">The first point.</param>
        /// <param name="b">The second point.</param>
        /// <param name="t">The weight.</param>
        /// <returns>The point (1 - <paramref name="t"/>)*<paramref name="a"/> + <paramref name="t"/>*<paramref name="b"/>.</returns>
        public static Point2D WeightedAverage(Point2D a, Point2D b, double t)
        {
            if (t <= 0)
            {
                return new Point2D(a);
            }
            else if (t >= 1)
            {
                return new Point2D(b);
            }
            else
            {
                double oneMinusT = 1 - t;

                return new Point2D((1 - t) * a + t * b.ToVector());
            }
        }