예제 #1
0
        /// <summary>
        /// Inflates balloon body and target point
        /// </summary>
        public static void InflateBalloon(ref Rectangle body, ref Point target, int deltaBody, int deltaTarget)
        {
            Point center = new Point(body.Left + body.Width / 2, body.Top + body.Height / 2);
              PolarPoint pp = new PolarPoint(center, target);

              body.Inflate(deltaBody, deltaBody);

              pp.R += deltaTarget;

              target = pp.Point;
              target.Offset(center.X, center.Y);
        }
예제 #2
0
        /// <summary>
        /// Inflates balloon body and target point
        /// </summary>
        public static void InflateBalloon(ref Rectangle body, ref Point target, int deltaBody, int deltaTarget)
        {
            Point      center = new Point(body.Left + body.Width / 2, body.Top + body.Height / 2);
            PolarPoint pp     = new PolarPoint(center, target);

            body.Inflate(deltaBody, deltaBody);

            pp.R += deltaTarget;

            target = pp.Point;
            target.Offset(center.X, center.Y);
        }
예제 #3
0
        /// <summary>
        /// Calculates callout balloon vertexes suitable for curve drawing
        /// </summary>
        /// <param name="body">Balloon body coordinates</param>
        /// <param name="target">A point of balloon leg attachment</param>
        /// <param name="legSweep">Length of balloon leg attachment breach at balloon body edge, expressed in radians (arc length). A value such as PI/16 yields good results</param>
        /// <returns>An array of vertex points</returns>
        public static Point[] VectorizeBalloon(Rectangle body, Point target, double legSweep)
        {
            List <Point> result = new List <Point>();

            Point      center = new Point(body.Left + body.Width / 2, body.Top + body.Height / 2);
            PolarPoint trg    = new PolarPoint(center, target);

            Point legStart = CartesianUtils.FindRayFromRectangleCenterSideIntersection(
                body,
                CartesianUtils.WrapAngle(trg.Theta, -legSweep / 2));

            Point legEnd = CartesianUtils.FindRayFromRectangleCenterSideIntersection(
                body,
                CartesianUtils.WrapAngle(trg.Theta, +legSweep / 2));

            result.Add(new Point(body.Left, body.Top));

            result.Add(new Point(body.Right, body.Top));

            result.Add(new Point(body.Right, body.Bottom));

            result.Add(new Point(body.Left, body.Bottom));

            result.Add(legStart);
            result.Add(target);
            result.Add(legEnd);

            //reorder points by azimuth so the curve can close and look like a balloon
            result.Sort(delegate(Point p1, Point p2)
            {
                PolarPoint pp1 = new PolarPoint(center, p1);
                PolarPoint pp2 = new PolarPoint(center, p2);

                if (pp1.Theta > pp2.Theta)
                {
                    return(-1);
                }
                else
                {
                    return(+1);
                }
            }
                        );

            return(result.ToArray());
        }
예제 #4
0
    /// <summary>
    /// Calculates callout balloon vertexes suitable for curve drawing
    /// </summary>
    /// <param name="body">Balloon body coordinates</param>
    /// <param name="target">A point of balloon leg attachment</param>
    /// <param name="legSweep">Length of balloon leg attachment breach at balloon body edge, expressed in radians (arc length). A value such as PI/16 yields good results</param>
    /// <returns>An array of vertex points</returns>
    public static Point[] VectorizeBalloon(Rectangle body, Point target, double legSweep)
    {

      List<Point> result = new List<Point>();

      Point center = new Point(body.Left + body.Width / 2, body.Top + body.Height / 2);
      PolarPoint trg = new PolarPoint(center, target);

      Point legStart = CartesianUtils.FindRayFromRectangleCenterSideIntersection(
                                 body,
                                 CartesianUtils.WrapAngle(trg.Theta, -legSweep / 2));

      Point legEnd = CartesianUtils.FindRayFromRectangleCenterSideIntersection(
                                 body,
                                 CartesianUtils.WrapAngle(trg.Theta, +legSweep / 2));

      result.Add(new Point(body.Left, body.Top));

      result.Add(new Point(body.Right, body.Top));

      result.Add(new Point(body.Right, body.Bottom));

      result.Add(new Point(body.Left, body.Bottom));

      result.Add(legStart);
      result.Add(target);
      result.Add(legEnd);

      //reorder points by azimuth so the curve can close and look like a balloon
      result.Sort(delegate(Point p1, Point p2)
      {
        PolarPoint pp1 = new PolarPoint(center, p1);
        PolarPoint pp2 = new PolarPoint(center, p2);

        if (pp1.Theta > pp2.Theta)
          return -1;
        else
          return +1;
      }
                  );

      return result.ToArray();
    }
예제 #5
0
    /// <summary>
    /// Returns a point of intersection between a ray cast from the center of a rectangle 
    ///  under certain polar coordinate angle and a rectangle side
    /// </summary>
    public static Point FindRayFromRectangleCenterSideIntersection(Rectangle rect, double theta)
    {
        Point center = new Point(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2);

        double rayLength = rect.Width > rect.Height ? rect.Width : rect.Height; //make ray "infinite" in comparison to rect
        
        if (rayLength < 100) rayLength = 100; //safeguard 

        PolarPoint rayEnd = new PolarPoint(rayLength, theta);//create ray "end" point

        double k = (rayEnd.Point.X!=0)? ((double)rayEnd.Point.Y) / ((double)rayEnd.Point.X) : 0; //get line incline  aka. y = kx

        int x, y;
        
        List<Point> lst = new List<Point>();
        
        //north
        x = center.X + ((k != 0) ? (int)((rect.Top - center.Y) / k) : 0);
        y = rect.Top;
        if ((x >= rect.Left) && 
            (x <= rect.Right))
           lst.Add(new Point(x, y));
       
        //south
        x = center.X + ((k != 0) ? (int)((rect.Bottom - center.Y) / k) : 0);
        y = rect.Bottom;
        if ((x >= rect.Left) &&
            (x <= rect.Right))
          lst.Add(new Point(x, y));
       
        //east
        x = rect.Right;
        y = center.Y + (int)(k * (rect.Right - center.X));
        if ((y >= rect.Top) &&
            (y <= rect.Bottom))
          lst.Add(new Point(x, y));
       
        //west
        x = rect.Left;
        y = center.Y + (int)(k * (rect.Left - center.X));
        if ((y >= rect.Top) &&
            (y <= rect.Bottom))
          lst.Add(new Point(x, y));
        
        Point minPoint = new Point(int.MaxValue, int.MaxValue);
        int minDistance = int.MaxValue;

        Point re = rayEnd.Point; //rayEnd is relative to absolute 0,0 
        re.Offset(center.X, center.Y); // need to make relative to rectangle center

        foreach (Point p in lst) //find closest point
        {
           int dst = Distance(p, re);
           
           if (dst < minDistance)
           {
             minPoint = p;
             minDistance = dst;
           }
        } 
        
        return minPoint;
      }
예제 #6
0
        public void PolarPointToPoint()
        {
            var polar = new PolarPoint(100D, Math.PI / 4);
              var decart = polar.Point;

              Assert.AreEqual(70D, Math.Floor((double)decart.X));
              Assert.AreEqual(70D, Math.Floor((double)decart.Y));
        }
예제 #7
0
파일: CartesianUtils.cs 프로젝트: rioka/nfx
        /// <summary>
        /// Returns a point of intersection between a ray cast from the center of a rectangle
        ///  under certain polar coordinate angle and a rectangle side
        /// </summary>
        public static Point FindRayFromRectangleCenterSideIntersection(Rectangle rect, double theta)
        {
            Point center = new Point(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2);

            double rayLength = rect.Width > rect.Height ? rect.Width : rect.Height; //make ray "infinite" in comparison to rect

            if (rayLength < 100)
            {
                rayLength = 100;                                                                       //safeguard
            }
            PolarPoint rayEnd = new PolarPoint(rayLength, theta);                                      //create ray "end" point

            double k = (rayEnd.Point.X != 0)? ((double)rayEnd.Point.Y) / ((double)rayEnd.Point.X) : 0; //get line incline  aka. y = kx

            int x, y;

            List <Point> lst = new List <Point>();

            //north
            x = center.X + ((k != 0) ? (int)((rect.Top - center.Y) / k) : 0);
            y = rect.Top;
            if ((x >= rect.Left) &&
                (x <= rect.Right))
            {
                lst.Add(new Point(x, y));
            }

            //south
            x = center.X + ((k != 0) ? (int)((rect.Bottom - center.Y) / k) : 0);
            y = rect.Bottom;
            if ((x >= rect.Left) &&
                (x <= rect.Right))
            {
                lst.Add(new Point(x, y));
            }

            //east
            x = rect.Right;
            y = center.Y + (int)(k * (rect.Right - center.X));
            if ((y >= rect.Top) &&
                (y <= rect.Bottom))
            {
                lst.Add(new Point(x, y));
            }

            //west
            x = rect.Left;
            y = center.Y + (int)(k * (rect.Left - center.X));
            if ((y >= rect.Top) &&
                (y <= rect.Bottom))
            {
                lst.Add(new Point(x, y));
            }

            Point minPoint    = new Point(int.MaxValue, int.MaxValue);
            int   minDistance = int.MaxValue;

            Point re = rayEnd.Point;       //rayEnd is relative to absolute 0,0

            re.Offset(center.X, center.Y); // need to make relative to rectangle center

            foreach (Point p in lst)       //find closest point
            {
                int dst = Distance(p, re);

                if (dst < minDistance)
                {
                    minPoint    = p;
                    minDistance = dst;
                }
            }

            return(minPoint);
        }
예제 #8
0
        public void PolarPointTheta()
        {
            var polar = new PolarPoint(100D, Math.PI);
              Assert.AreEqual(314D, Math.Floor(polar.Theta * 100D));

              polar.Theta = 1.18D;
              Assert.AreEqual(118D, Math.Floor(polar.Theta * 100D));
        }
예제 #9
0
        public void PolarPointRadius()
        {
            var polar = new PolarPoint(100D, Math.PI);
              Assert.AreEqual(100D, polar.R);

              polar.R = 125D;
              Assert.AreEqual(125D, polar.R);
        }
예제 #10
0
        public void PolarPointIsEqual()
        {
            var polar1 = new PolarPoint(100D, 1.2D);
              var polar2 = new PolarPoint(10D, 2.17D);
              var polar3 = new PolarPoint(100D, 1.2D);

              Assert.AreNotEqual(polar1, polar2);
              Assert.AreEqual(polar1, polar3);
        }
예제 #11
0
 public void PolarPointInvalid()
 {
     try
       {
     var pp = new PolarPoint(100, 789);
     Assert.Fail();
       }
       catch (NFXException ex)
       {
     Assert.IsTrue(ex.Message.Contains("angle"));
       }
 }
예제 #12
0
        public void PointToPolarPoint()
        {
            var center = new Point(0, 0);
              var pnt = new Point(150, 0);

              var polar = new PolarPoint(center, pnt);

              Assert.AreEqual(150D, polar.R);
              Assert.AreEqual(0D, polar.Theta);
        }