Exemple #1
0
        private void panel_curve_MouseDown(object sender, MouseEventArgs e)
        {
            isDragging         = true;
            status_label1.Text = "isDragging: true";
            Point point_panel = panel_curve.PointToScreen(new Point(0, 0));
            Point p           = new Point(MousePosition.X - point_panel.X, MousePosition.Y - point_panel.Y);

            if ((p1.ToVector() - p.ToVector()).Magnitude < 10)
            {
                draggingPoint = 1;
            }
            else if ((p2.ToVector() - p.ToVector()).Magnitude < 10)
            {
                draggingPoint = 2;
            }
            else if ((p3.ToVector() - p.ToVector()).Magnitude < 10)
            {
                draggingPoint = 3;
            }
            else if ((p4.ToVector() - p.ToVector()).Magnitude < 10)
            {
                draggingPoint = 4;
            }
            else
            {
                draggingPoint = 0;
            }
        }
        private static void CheckNormal(Triangle t, Point center)
        {
            // arrange
            var normal             = t.GetNormal();
            var p0                 = t.ToVectors().Item1;
            var vertexDistance     = (p0 - center.ToVector()).Length();
            var withNormalDistance = (p0 + normal - center.ToVector()).Length();

            // assert
            Assert.IsTrue(withNormalDistance > vertexDistance);
        }
Exemple #3
0
 public IrregularCell(Point lb, Point rb, Point rt, Point lt)
 {
     leftTop     = lt.ToVector();
     leftBottom  = lb.ToVector();
     rightTop    = rt.ToVector();
     rightBottom = rb.ToVector();
 }
Exemple #4
0
    public static void LoopEdges(this Face face, Rectangle rectangle, bool clipEdges, System.Action <Vector2, Vector2> OnEdge)
    {
        var edge  = face.Edge;
        var first = edge.Origin.ID;

        do
        {
            //extract the vertices position
            Point p1 = new Point(edge.Origin.X, edge.Origin.Y);
            Point p2 = new Point(edge.Twin.Origin.X, edge.Twin.Origin.Y);

            if (clipEdges)
            {
                if ((rectangle.Contains(p1) && !rectangle.Contains(p2)))
                {
                    IntersectionHelper.BoxRayIntersection(rectangle, p1, p2, ref p2); //case 1
                }
                else if (!rectangle.Contains(p1) && rectangle.Contains(p2))
                {
                    IntersectionHelper.BoxRayIntersection(rectangle, p2, p1, ref p1); //case 2
                }
                else if (!rectangle.Contains(p1) && !rectangle.Contains(p2))          //case 3
                {
                    edge = edge.Next;
                    continue;
                }
            }

            Vector2 origin = p1.ToVector();
            Vector2 end    = p2.ToVector();

            OnEdge?.Invoke(origin, end);
            edge = edge.Next;
        } while (edge != null && edge.Origin.ID != first);
    }
Exemple #5
0
        public static SingularityBullet CreateSingularityBullet(SceneMgr mgr, Point point, Player plr)
        {
            Vector position  = new Vector(plr.GetBaseLocation().X + plr.GetBaseLocation().Width / 2, plr.GetBaseLocation().Y);
            Vector direction = point.ToVector() - position;

            direction.Normalize();

            SingularityBullet bullet = new SingularityBullet(mgr, IdMgr.GetNewId(mgr.GetCurrentPlayer().GetId()));

            bullet.Position  = position;
            bullet.Owner     = plr;
            bullet.Radius    = 2;
            bullet.Damage    = plr.Data.BulletDamage;
            bullet.Direction = direction;
            bullet.Color     = plr.Data.PlayerColor;

            PointCollisionShape cs = new PointCollisionShape();

            cs.Center             = bullet.Center;
            bullet.CollisionShape = cs;

            LinearMovementControl lmc = new LinearMovementControl();

            lmc.Speed = plr.Data.BulletSpeed;
            bullet.AddControl(lmc);

            bullet.AddControl(new SingularityBulletCollisionReactionControl());
            bullet.AddControl(new StickyPointCollisionShapeControl());

            bullet.SetGeometry(SceneGeometryFactory.CreateConstantColorEllipseGeometry(bullet));

            return(bullet);
        }
Exemple #6
0
 private void RepositionSprite()
 {
     if (HasSprite())
     {
         Sprite.transform.position = Position.ToVector();
     }
 }
Exemple #7
0
        public void ShootInGame(Point target)
        {
            var inGameTarget = target.ToVector() - Bias;

            inGameTarget.Y *= -1;
            SetTurn(Turn.Shoot(inGameTarget));
        }
Exemple #8
0
        public Point3D ClosestPoint(Point3D point)
        {
            Vector3D pv = point.ToVector();
            double   d  = Normal.DotProduct(pv - Point.ToVector());

            return((pv - (Normal * d)).ToPoint());
        }
Exemple #9
0
        private SKPoint ApplyMatrix(Point mercatorPoint)
        {
            Vector <double> point  = mercatorPoint.ToVector();
            Vector <double> result = _MercatorMatrix.Multiply(point);

            return(result.ToSKPoint());
        }
    public static void BorderLooping(this Face face, Rectangle rectangle, bool clipEdges, System.Action <Vector2, Vector2> OnEdge)
    {
        var border = face.Edge;
        var first  = border.Origin.ID;

        do
        {
            // vertices position
            Point p1 = new Point(border.Origin.X, border.Origin.Y);
            Point p2 = new Point(border.Twin.Origin.X, border.Twin.Origin.Y);

            if (clipEdges)
            {
                if ((rectangle.Contains(p1) && !rectangle.Contains(p2)))
                {
                    IntersectionHelper.BoxRayIntersection(rectangle, p1, p2, ref p2);
                }
                else if (!rectangle.Contains(p1) && rectangle.Contains(p2))
                {
                    IntersectionHelper.BoxRayIntersection(rectangle, p2, p1, ref p1);
                }
                else if (!rectangle.Contains(p1) && !rectangle.Contains(p2))
                {
                    border = border.Next;
                    continue;
                }
            }

            Vector2 origin = p1.ToVector();
            Vector2 end    = p2.ToVector();

            OnEdge?.Invoke(origin, end);
            border = border.Next;
        } while (border != null && border.Origin.ID != first);
    }
Exemple #11
0
		public IrregularCell(Point lb, Point rb, Point rt, Point lt)
		{
			leftTop = lt.ToVector();
			leftBottom = lb.ToVector();
			rightTop = rt.ToVector();
			rightBottom = rb.ToVector();
		}
Exemple #12
0
        public bool ClosestPoints(Line3D b, out Point3D pa, out Point3D pb)
        {
            pa = null;
            pb = null;

            if (Vector == b.Vector || Vector == -b.Vector)
            {
                return(false);
            }

            Vector3D p0  = Point.ToVector();
            Vector3D p1  = b.Point.ToVector();
            Vector3D d0  = Vector;
            Vector3D d1  = b.Vector;
            Vector3D d0n = d0.Normalize();

            Vector3D c = new Vector3D();
            Vector3D d = new Vector3D();

            d.X = d1.X - d0n.X * (d0.X * d1.X + d0.Y * d1.Y + d0.Z * d1.Z);
            c.X = p1.X - p0.X + d0n.X * (d0.X * p0.X + d0.Y * p0.Y + d0.Z * p0.Z);

            d.Y = d1.Y - d0n.Y * (d0.X * d1.X + d0.Y * d1.Y + d0.Z * d1.Z);
            c.Y = p1.Y - p0.Y + d0n.Y * (d0.X * p0.X + d0.Y * p0.Y + d0.Z * p0.Z);

            d.Z = d1.Z - d0n.Z * (d0.X * d1.X + d0.Y * d1.Y + d0.Z * d1.Z);
            c.Z = p1.Z - p0.Z + d0n.Z * (d0.X * p0.X + d0.Y * p0.Y + d0.Z * p0.Z);

            double t = -(c.X * d.X + c.Y * d.Y + c.Z * d.Z) / (d.X * d.X + d.Y * d.Y + d.Z * d.Z);

            pb = b.Point + (b.Vector * t);
            pa = ClosestPoint(pb);

            return(true);
        }
Exemple #13
0
        public Point3D ClosestPoint(Point3D point)
        {
            double n = (point.ToVector() - Point.ToVector()).DotProduct(Vector);
            double d = Vector.Length();

            return(Point + (Vector * (n / d)));
        }
        public override void HandleInput()
        {
            if (InputManager.IsMouseButtonPressed(MouseButton.Left))
            {
                if (InputManager.IsMouseButtonTriggered(MouseButton.Left))
                {
                    lastMouseDown = InputManager.MousePosition;
                }

                if (world.CanDrag)
                {
                    Vector2 delta = InputManager.LastMousePosition.ToVector() -
                                    InputManager.MousePosition.ToVector();

                    world.Camera.Move(-delta);
                }
            }
            else if (InputManager.IsMouseButtonClicked(MouseButton.Left))
            {
                var current = InputManager.MousePosition.ToVector();

                float distance = Vector2.Distance(current,
                                                  lastMouseDown.ToVector());

                if (distance <= clickDistanceThreshold)
                {
                    world.OnClick(current - world.Camera.RawPosition);
                }
            }

            if (InputManager.IsKeyTriggered(Keys.B))
            {
                ScreenManager.AddScreen(new BuildingListScreen(world));
            }

            var mouse = InputManager.MousePosition.ToVector() - world.Camera.RawPosition;

            var selection = world.GetNodePosition(mouse);

            if (InputManager.IsMouseButtonTriggered(MouseButton.Right))
            {
                if (new Rectangle(0, 0, MarsWorld.Size.X, MarsWorld.Size.Y).Contains(selection))
                {
                    var type = InputManager.IsKeyPressed(Keys.LeftShift) ?
                               Enemy.Tank : Enemy.Basic;

                    for (int i = 0; i < 25; i++)
                    {
                        var offset = new Vector2(random.Next(250), random.Next(250));
                        world.AddEnemy(type, mouse - new Vector2(10) + offset);
                    }
                }
            }

            if (InputManager.IsKeyTriggered(Keys.OemTilde))
            {
                MarsWorld.Debug = !MarsWorld.Debug;
            }
        }
Exemple #15
0
        public static Vector GetVectorTo(this Point p1, Point p2)
        {
            var v1 = p1.ToVector();
            var v2 = p2.ToVector();
            var v  = v1 - v2;

            return(v);
        }
Exemple #16
0
    public static Point ClosestPointTriangle(Point _p, Triangle t)
    {
        Point point = new Point(_p.X, _p.Y, _p.Z);
        //create plane out fo triangle
        Plane plane = new Plane(t.p0, t.p1, t.p2);

        //get closest point to plane
        point = ClosestPoint(plane, point);

        if (PointInTriangle(t, point))
        {
            //if point is in triangle, return it
            return(new Point(point.X, point.Y, point.Z));
        }

        //break triangle down into Line components
        Line AB = new Line(t.p0, t.p1);
        Line BC = new Line(t.p1, t.p2);
        Line CA = new Line(t.p2, t.p0);

        //find closest point to each line
        Point c1 = ClosestPoint(AB, point);
        Point c2 = ClosestPoint(BC, point);
        Point c3 = ClosestPoint(CA, point);

        //mag is magnitudeSquared. Magnitude to unknown point
        float mag1 = (point.ToVector() - c1.ToVector()).LengthSquared();
        float mag2 = (point.ToVector() - c2.ToVector()).LengthSquared();
        float mag3 = (point.ToVector() - c3.ToVector()).LengthSquared();

        //find smallest magnitude(shortest distance)
        float min = System.Math.Min(mag1, mag2);

        min = System.Math.Min(min, mag3);

        if (min == mag1)
        {
            return(c1);
        }
        else if (min == mag2)
        {
            return(c2);
        }
        return(c3);
    }
Exemple #17
0
        public IConvexHull FindConvexHull(IList <PlanePoint> points)
        {
            if (points.Count == 3)
            {
                return(new ConvexHull2d(points));
            }
            List <PlanePoint> hullPoints = new List <PlanePoint>();
            int    first             = points.IndexOf(points.Min());
            Vector currentVector     = new Vector(new double[] { 0, -1 });
            int    currentPlanePoint = first;

            bool[] processedPoint = new bool[points.Count];
            do
            {
                hullPoints.Add(points[currentPlanePoint]);
                double maxCos    = double.MinValue;
                double maxLen    = double.MinValue;
                int    next      = 0;
                Vector maxVector = currentVector;
                for (int i = 0; i < points.Count; i++)
                {
                    if (currentPlanePoint == i || processedPoint[i])
                    {
                        continue;
                    }
                    Vector newVector = Point.ToVector(points[currentPlanePoint], points[i]);
                    double newCos    = currentVector * newVector;
                    newCos /= newVector.Length * currentVector.Length;
                    if (Tools.GT(newCos, maxCos))
                    {
                        maxCos    = newCos;
                        next      = i;
                        maxLen    = Point.Length(points[currentPlanePoint], points[next]);
                        maxVector = newVector;
                    }
                    else if (Tools.EQ(maxCos, newCos))
                    {
                        double dist = Point.Length(points[currentPlanePoint], points[i]);
                        if (Tools.LT(maxLen, dist))
                        {
                            next      = i;
                            maxVector = newVector;
                            maxLen    = dist;
                        }
                    }
                }

                processedPoint[next] = true;
                currentPlanePoint    = next;
                currentVector        = maxVector;
            } while (first != currentPlanePoint);

            ConvexHull2d hull = new ConvexHull2d(hullPoints);

            return(hull);
        }
Exemple #18
0
        private Vector2 CalculateMovement(Point current, float amount)
        {
            Vector2 result = new Vector2();
            Vector2 cVector = current.ToVector();
            Vector2 dVector = destination.ToVector();

            Vector2.SmoothStep(ref cVector, ref dVector, amount, out result);

            return result;
        }
Exemple #19
0
        public Hyperplane FindFirstPlane(IList <PlanePoint> points)
        {
            int dim      = points[0].Dim;
            int minIndex = points.IndexOf(points.Min());

            Vector[] mainBasis        = GetFirstBasis(dim);
            bool[]   availableVectors = new bool[points.Count];
            Vector[] vectors          = points.Select(point => Point.ToVector(points[minIndex], point)).ToArray();
            availableVectors[minIndex] = true;
            Vector[] subBasis   = mainBasis[1..^ 0];
Exemple #20
0
        public static Vector[] ToVectors(this IList <PlanePoint> points)
        {
            Vector[] vectors    = new Vector[points.Count - 1];
            Point    firstPoint = points[0];

            for (int i = 1; i < points.Count; i++)
            {
                vectors[i - 1] = Point.ToVector(firstPoint, points[i]);
            }

            return(vectors);
        }
        public override void Initialize(int width, int height)
        {
            GL.Enable(EnableCap.CullFace);
            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
            GL.PointSize(2f);

            bool[] results = new bool[] { true, true, true, true, false, false, false };
            for (int i = 0; i < testPoints.Length; ++i)
            {
                bool collision = Collisions.PointInSphere(testSphere, testPoints[i]);
                if (collision != results[i])
                {
                    System.Console.ForegroundColor = System.ConsoleColor.Red;
                }
                System.Console.Write("Point: " + testPoints[i]);
                if (collision)
                {
                    System.Console.WriteLine(" is in sphere");
                }
                else
                {
                    System.Console.WriteLine(" is not in sphere");
                }
                System.Console.ResetColor();
            }

            Vector3 expected = new Vector3(0.719944f, 0.719944f, 1.960392f);
            Point   closest  = Collisions.ClosestPoint(testSphere, farPoint);

            if (expected != closest.ToVector())
            {
                System.Console.ForegroundColor = System.ConsoleColor.Red;
            }
            System.Console.WriteLine("Closest point: " + closest);
            if (expected != closest.ToVector())
            {
                System.Console.WriteLine("Expected: " + expected.X + ", " + expected.Y + ", " + expected.Z);
            }
            System.Console.ResetColor();
        }
Exemple #22
0
    public static bool SpherePlaneIntersect(Sphere sphere, Plane plane)
    {
        Point closest = Collisions.ClosestPoint(plane, sphere.Position);

        Vector3 closestPoint = closest.ToVector();

        Vector3 spherePos = sphere.Position.ToVector();

        Vector3 distance = spherePos - closestPoint;

        float distSq   = Vector3.LengthSquared(distance);
        float radiusSq = sphere.Radius * sphere.Radius;

        return(distSq <= radiusSq);
    }
        public void PointExtensionToVectorTest()
        {
            // arrange
            var p = new Point(5, 6, 7)
            {
            };

            // act
            var v = p.ToVector();

            // assert
            Assert.IsTrue(v[0] == 5);
            Assert.IsTrue(v[1] == 6);
            Assert.IsTrue(v[2] == 7);
        }
Exemple #24
0
        public Rectangle PutNextRectangle(Size rectangleSize)
        {
            var candidates = new List <Rectangle>();

            for (var angle = 0.0; angle < 2 * Math.PI; angle += AngleStep)
            {
                var rectCenter = Vector.FromPolar(GetPossibleRadius(rectangleSize), angle) + center.ToVector();
                var rect       = CreateRectangle(rectCenter.ToDrawingPoint(), rectangleSize);
                candidates.Add(ShiftCloserToCloud(rect));
            }
            var result = candidates.OrderBy(rect => rect.GetCenter().DistanceTo(center)).First();

            rectangles.Add(result);
            return(result);
        }
Exemple #25
0
    public static bool SphereIntersect(Triangle triangle, Sphere sphere)
    {
        //get closest point on triangle to center of sphere
        Point p = ClosestPointTriangle(sphere.Position, triangle);

        //check distanceSq between center and point on triangle
        float distSq = Vector3.LengthSquared(sphere.vPosition - p.ToVector());

        //if distance is < r2 then there is a collision
        if (distSq < (sphere.Radius * sphere.Radius))
        {
            return(true);
        }

        return(false);
    }
Exemple #26
0
        public override void Initialize(int width, int height)
        {
            // Seeing the back face of a square gives a better
            // overview of the actual geometry
            //GL.Enable(EnableCap.CullFace);
            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
            GL.PointSize(2f);

            Point closest = Collisions.ClosestPoint(testAABBs[0], secondFarPoint);

            if (closest.ToVector() != new Vector3(2f, 3.4f, 1f))
            {
                System.Console.ForegroundColor = System.ConsoleColor.Red;
            }
            System.Console.WriteLine("closest: " + closest + " / 2, 3.4, 1");
            System.Console.ResetColor();
        }
Exemple #27
0
        /// <summary>
        /// Drags the grid between two mouse points
        /// </summary>
        /// <param name="mouse"> Current mouse position </param>
        /// <param name="lastMouse"> Last mouse position </param>
        void dragGrid(Point mouse, Point lastMouse)
        {
            // delta movement between our two points
            var delta = (mouse.ToVector() - lastMouse.ToVector());

            // add the amount we've dragged to the camera position
            gridCamera += delta;

            // clamp camera x value to show only the grid
            gridCamera.X = MathHelper.Clamp(gridCamera.X,
                                            -(gridBounds.Width - gridViewport.Width) + gridNodeSize.X,
                                            -gridNodeSize.X);

            // clamp camera y value to show only the grid
            gridCamera.Y = MathHelper.Clamp(gridCamera.Y,
                                            -(gridBounds.Height - gridViewport.Height) + gridNodeSize.Y,
                                            -gridNodeSize.Y);
        }
Exemple #28
0
        public static Vector SetOrientationNormal(this Vector normal, PlanePoint mainPoint, IEnumerable <PlanePoint> innerPoints)
        {
            foreach (PlanePoint planePoint in innerPoints)
            {
                Vector vector     = Point.ToVector(mainPoint, planePoint.GetPoint(mainPoint.Dim));
                double dotProduct = vector * normal;
                if (Tools.EQ(dotProduct))
                {
                    continue;
                }
                if (Tools.GT(dotProduct))
                {
                    normal = -normal;
                }

                return(normal);
            }
            throw new ArgumentException("All points lie on the plane.");
        }
Exemple #29
0
        /// <summary>
        /// This is for making a 2D circle out of triangles.  This takes a point on the edge of a circle and gives the corresponding point
        /// on an inner and outer circle.  It then does a projection onto the surface of a sphere (the sphere should be at least 1.5 times
        /// larger than the drawn circle, or it will look bad)
        /// </summary>
        private static (Point3D inner, Point3D mid, Point3D outer) GetCirclePoints(Point pointOnCircle, double circleRadius, double thickness, double sphereRadius)
        {
            Vector asVect = pointOnCircle.ToVector();

            double half        = thickness / 2;
            double innerRadius = Math.Max(0, circleRadius - half);
            double outerRadius = circleRadius + half;

            Vector inner = asVect * innerRadius;
            Vector mid   = asVect * circleRadius;
            Vector outer = asVect * outerRadius;

            return
                (
                Math3D.ProjectPointOntoSphere(inner.X, inner.Y, sphereRadius),
                Math3D.ProjectPointOntoSphere(mid.X, mid.Y, sphereRadius),
                Math3D.ProjectPointOntoSphere(outer.X, outer.Y, sphereRadius)
                );
        }
Exemple #30
0
    public static Point ClosestPoint(Line ab, Point c, out float t)
    {
        Vector3 a = new Vector3(ab.Start.X, ab.Start.Y, ab.Start.Z);
        Vector3 b = new Vector3(ab.End.X, ab.End.Y, ab.End.Z);

        //project c onto b, then find the
        //parametrized position d(t) = a+t*(b-a)
        //t = Dot(c - a, ab) / Dot(ab, ab);
        t = Vector3.Dot((c.ToVector() - a), ab.ToVector()) / Vector3.Dot(ab.ToVector(), ab.ToVector());

        //clamp t to 0-1 range
        //if t is outside range, it is outside line
        t = Clamp(t, 1f, 0f);

        //compute project position from clamped t
        Point distance = new Point(a + (ab.ToVector() * t));

        //return result
        return(distance);
    }
    private Characteristics.Corner MakeCorner(Point point)
    {
        if (point == null)
        {
            return(null);
        }
        for (int i = (int)(point.X) - 1; i <= (int)(point.X) + 1; i++)
        {
            if (_cornerMap.ContainsKey(i))
            {
                foreach (Characteristics.Corner corner in _cornerMap[i])
                {
                    float dx = (float)point.X - corner.pos.x;
                    float dy = (float)point.Y - corner.pos.y;
                    if (Mathf.Sqrt(dx * dx + dy * dy) < Mathf.Epsilon)
                    {
                        return(corner);
                    }
                }
            }
        }

        int index = (int)point.X;

        if (!_cornerMap.ContainsKey(index) || _cornerMap[index] == null)
        {
            _cornerMap[index] = new List <Characteristics.Corner>();
        }
        Characteristics.Corner q = new Characteristics.Corner
        {
            id        = data.corners.Count,
            pos       = point.ToVector(),
            border    = (point.X == 0 || point.X == rectangle.Width || point.Y == 0 || point.Y == rectangle.Height),
            touches   = new List <Characteristics.Center>(),
            protrudes = new List <Characteristics.Border>(),
            adjacent  = new List <Characteristics.Corner>()
        };
        data.corners.Add(q);
        _cornerMap[index].Add(q);
        return(q);
    }
Exemple #32
0
    public static Point ClosestPoint(Ray r, Point c)
    {
        //t is local, no need to pass it out of
        float t = 0f;
        //construct line segment out of ray
        Point rNormPos = new Point(r.Normal.X + r.Position.X,
                                   r.Normal.Y + r.Position.Y,
                                   r.Normal.Z + r.Position.Z);
        Line ab = new Line(r.Position, rNormPos);

        Vector3 a = new Vector3(r.Position.X, r.Position.Y, r.Position.Z);
        Vector3 b = new Vector3(rNormPos.X, rNormPos.Y, rNormPos.Z);

        t = Vector3.Dot(c.ToVector() - a, ab.ToVector()) / Vector3.Dot(ab.ToVector(), ab.ToVector());

        t = Max(t, 0f);

        Point d = new Point(a + (r.Normal * t));

        return(d);
    }
        public static Point GetClippingPoint(Size size, Point s, Point t)
        {
            double[] sides = new double[4];
            sides[0] = (s.X - size.Width / 2.0 - t.X) / (s.X - t.X);
            sides[1] = (s.Y - size.Height / 2.0 - t.Y) / (s.Y - t.Y);
            sides[2] = (s.X + size.Width / 2.0 - t.X) / (s.X - t.X);
            sides[3] = (s.Y + size.Height / 2.0 - t.Y) / (s.Y - t.Y);

            double fi = 0;
            for (int i = 0; i < 4; i++)
            {
                if (sides[i] <= 1)
                    fi = Math.Max(fi, sides[i]);
            }
            if (fi == 0)
            {
                fi = double.PositiveInfinity;
                for (int i = 0; i < 4; i++)
                    fi = Math.Min(fi, Math.Abs(sides[i]));
                fi *= -1;
            }

            return t + fi * (s.ToVector() - t);
        }