예제 #1
0
        public static Polygon Ellipse(Point center, double xRadius, double yRadius)
        {
            int precision = (int)GMath.Ceiling(GMath.Pi * GMath.Abs(xRadius + yRadius));

            if (precision <= 0)
            {
                return(new Polygon(new[] { center }));
            }
            double dt = GMath.Tau / precision;
            double c = GMath.Cos(dt), s = GMath.Sin(dt);

            double x = 1, y = 0, tmp;

            var pts = new Point[precision];

            for (int i = 0; i < precision; i++)
            {
                pts[i] = new Point(center.X + x * xRadius, center.Y + y * yRadius);

                tmp = x;
                x   = c * x - s * y;
                y   = s * tmp + c * y;
            }

            return(new Polygon(pts));
        }
예제 #2
0
        public static Color FromHsv(Angle h, double s, double v, int a)
        {
            var H = h.Degrees / 60;

            s = GMath.Median(0, s, 1);
            v = GMath.Median(0, v, 1);
            var C = v * s;
            var X = C * (1 - GMath.Abs(H % 2 - 1));
            var m = v - C;

            double R, G, B;

            switch ((int)H)
            {
            case 0: R = C; G = X; B = 0; break;

            case 1: R = X; G = C; B = 0; break;

            case 2: R = 0; G = C; B = X; break;

            case 3: R = 0; G = X; B = C; break;

            case 4: R = X; G = 0; B = C; break;

            default: R = C; G = 0; B = X; break;
            }

            return(FromRgba((int)(255 * (R + m)), (int)(255 * (G + m)), (int)(255 * (B + m)), a));
        }
예제 #3
0
        /// <summary>
        /// Applies a rotation transformation to this GRaff.Matrix.
        /// This is equivalent to Matrix.Rotation(a) * this.
        /// </summary>
        /// <param name="a">The angle to rotate by.</param>
        /// <returns>This GRaff.Matrix, after the transformation.</returns>
        public Matrix Rotate(Angle a)
        {
            double c = GMath.Cos(a), s = GMath.Sin(a);

            return(new Matrix(M00 * c - M10 * s, M01 * c - M11 * s, M02 * c - M12 * s,
                              M00 * s + M10 * c, M01 * s + M11 * c, M02 * s + M12 * c));
        }
예제 #4
0
        private Rectangle?_intersectionAbs(Rectangle other)
        {
            Rectangle thisAbs = this.Abs, otherAbs = other.Abs;
            double    l = GMath.Max(thisAbs.Left, otherAbs.Left), r = GMath.Min(thisAbs.Right, otherAbs.Right),
                      t = GMath.Max(thisAbs.Top, otherAbs.Top), b = GMath.Min(thisAbs.Bottom, otherAbs.Bottom);

            if (l > r || t > b)
            {
                return(null);
            }
            else
            {
                return(new Rectangle(l, t, r - l, b - t));
            }
        }
예제 #5
0
        public static Polygon Circle(Point center, double radius)
        {
            if (radius == 0)
            {
                return(new Polygon(new[] { center }));
            }

            int precision = (int)GMath.Ceiling(GMath.Tau * GMath.Abs(radius));

            if (precision < 2)
            {
                precision = 2;
            }

            return(Regular(precision, radius, center));
        }
예제 #6
0
        public Polygon(IEnumerable <Point> pts)
        {
            _pts = pts.ToArray();

            if (_pts.Length <= 2)
            {
                return;
            }

            double sum = 0;
            Angle  a;
            Vector previous, next;

            previous = Edge(-1).Offset;
            next     = Edge(0).Offset;

            a = next.Direction - previous.Direction;
            if (a.Degrees > 180)
            {
                Array.Reverse(_pts);
                previous = Edge(-1).Offset;
                next     = Edge(0).Offset;
                a        = next.Direction - previous.Direction;
            }
            sum += a.Degrees;

            for (int i = 1; i < _pts.Length; i++)
            {
                previous = next;
                next     = Edge(i).Offset;
                a        = next.Direction - previous.Direction;
                if (a.Degrees > 180)
                {
                    throw new ArgumentException("The points must specify a convex polygon.");
                }
                sum += a.Degrees;
            }

            if (GMath.Abs(sum - 360) > GMath.DefaultDelta)
            {
                throw new ArgumentException($"The points must specify a convex polygon with winding number equal to 1. (Winding is {sum} degrees)");
            }
        }
예제 #7
0
        public static Polygon Regular(int degree, double radius, Point center)
        {
            Contract.Requires <ArgumentOutOfRangeException>(degree >= 2);

            double dt = GMath.Tau / degree;
            double c = GMath.Cos(dt), s = GMath.Sin(dt);

            double x = 0, y = -radius, tmp;

            Point[] pts = new Point[degree];

            for (int i = 0; i < degree; i++)
            {
                pts[i] = new Point(center.X + x, center.Y + y);

                tmp = x;
                x   = c * x - s * y;
                y   = s * tmp + c * y;
            }

            return(new Polygon(pts));
        }
예제 #8
0
        /// <summary>
        /// Returns whether this line intersects the other.
        /// Edge cases such as if the endpoint of one line lies on the other line
        /// have no definite behaviour.
        /// </summary>
        public bool Intersects(Line other)
        {
            var n = LeftNormal;
            var h = n.Dot(other.Origin - Origin);

            if (h * n.Dot(other.Destination - Origin) > 0)
            {
                return(false);
            }
            else if (h * n.Dot(other.Destination - Origin) == 0)
            {
                if ((Offset.Dot(other.Origin - Origin) < 0 && Offset.Dot(other.Destination - Origin) < 0) ||
                    (Offset.Dot(other.Origin - Destination) > 0 && Offset.Dot(other.Destination - Destination) > 0))
                {
                    return(false);
                }
                else
                {
                    return(true);
                }
            }

            var angle = other.Offset.Angle(this.Offset);

            if (angle.Degrees == 0 || angle.Degrees == 180)
            {
                if (h != 0)
                {
                    return(false);
                }
                return(_isPointAdjacent(other.Origin) || _isPointAdjacent(other.Destination));
            }

            var sign = n.Dot(other.Offset) > 0 ? 1 : -1;
            var p    = other.Origin - sign * new Vector(h / GMath.Sin(angle), angle);

            return(_isPointAdjacent(p));
        }
예제 #9
0
 /// <summary>
 /// Finds the direction of the vector from the origin to the specified point.
 /// </summary>
 /// <param name="p">The point.</param>
 /// <returns>The direction of the vector from the origin to the specified point.</returns>
 public static Angle Direction(Point p)
 => GMath.Atan2(p.Y, p.X);
예제 #10
0
 /// <summary>
 /// Finds the direction of the vector from the origin to the specified (x, y) point.
 /// </summary>
 /// <param name="x">The x-coordinate.</param>
 /// <param name="y">The y-coordinate.</param>
 /// <returns>The direction of the vector from the origin to the specified point.</returns>
 public static Angle Direction(double x, double y) => GMath.Atan2(y, x);
예제 #11
0
 /// <summary>
 /// Creates a GRaff.Angle with a value specified in degrees.
 /// </summary>
 /// <param name="degrees">The angle, in degrees</param>
 /// <returns>the created GRaff.Angle</returns>
 public static Angle Deg(double degrees)
 => new Angle(GMath.RoundULong(GMath.Remainder((degrees * degToData), ulong.MaxValue)));
예제 #12
0
 /// <summary>
 /// Creates a GRaff.Angle with a value specified in radians.
 /// </summary>
 /// <param name="radians">The angle, in radians.</param>
 /// <returns>the created GRaff.Angle</returns>
 public static Angle Rad(double radians)
 => new Angle(GMath.RoundULong(GMath.Remainder((radians * radToData), ulong.MaxValue)));
예제 #13
0
 /// <summary>
 /// Finds the direction of the vector from the point (x1,y1) to the point (x2,y2).
 /// </summary>
 /// <param name="xFrom">The x-coordinate of the first point.</param>
 /// <param name="yFrom">The y-coordinate of the first point.</param>
 /// <param name="xTo">The x-coordinate of the second point.</param>
 /// <param name="yTo">The y-coordinate of the second point.</param>
 /// <returns>The direction of the vector from the first to the second point.</returns>
 public static Angle Direction(double xFrom, double yFrom, double xTo, double yTo)
 => GMath.Atan2(yTo - yFrom, xTo - xFrom);
예제 #14
0
 /// <summary>
 /// Returns a hash code for this GRaff.Matrix.
 /// </summary>
 /// <returns>An integer value that specifies a hash value for this GRaff.Matrix.</returns>
 public override int GetHashCode()
 => GMath.HashCombine(M00.GetHashCode(), M01.GetHashCode(), M02.GetHashCode(), M10.GetHashCode(), M11.GetHashCode(), M12.GetHashCode());
예제 #15
0
 public Vector(double magnitude, Angle direction)
     : this()
 {
     X = magnitude * GMath.Cos(direction);
     Y = magnitude * GMath.Sin(direction);
 }
예제 #16
0
 /// <summary>
 /// Returns a hash code for this GRaff.Vector.
 /// </summary>
 /// <returns>An integer value that specifies a hash value for this GRaff.Vector.</returns>
 public override int GetHashCode()
 => GMath.HashCombine(X.GetHashCode(), Y.GetHashCode());
예제 #17
0
 /// <summary>
 /// Returns a hash code for this GRaff.Rectangle.
 /// </summary>
 /// <returns>An integer value that specifies a hash value for this GRaff.Rectangle.</returns>
 public override int GetHashCode()
 => GMath.HashCombine(Left.GetHashCode(), Top.GetHashCode(), Width.GetHashCode(), Height.GetHashCode());
예제 #18
0
 public Point Project(Point pt)
 => new Point(GMath.Median(Left, pt.X, Right), GMath.Median(Top, pt.Y, Bottom));
예제 #19
0
 /// <summary>
 /// Returns a hash code for this GRaff.IntRectangle.
 /// </summary>
 /// <returns>An integer value that specifies a hash value for this GRaff.IntRectangle.</returns>
 public override int GetHashCode()
 => GMath.HashCombine(Left, Top, Width, Height);
예제 #20
0
 /// <summary>
 /// Returns a hash code for this GRaff.IntVector.
 /// </summary>
 /// <returns>An integer value that specifies a hash value for this GRaff.IntVector.</returns>
 public override int GetHashCode()
 => GMath.HashCombine(X, Y);
예제 #21
0
 /// <summary>
 /// Creates a new GRaff.Color, with the same color channels as this instance, but with the new specified opacity.
 /// </summary>
 /// <param name="opacity">The opacity of the new color. 0.0 means it is completely transparent, and 1.0 means it is completely opaque.</param>
 /// <returns>A new GRaff.Color with the same color as this instance, but with an alpha channel corresponding to the specified opacity.</returns>
 public Color Transparent(double opacity) => new Color(R, G, B, (byte)GMath.Round(255.0 * GMath.Median(0.0, opacity, 1.0)));
예제 #22
0
 /// <summary>
 /// Returns a random number that is distributed in accordance with standard normal distribution.
 /// I.e. a normally distributed variable with mean 0 and standard deviation 1.
 /// </summary>
 /// <param name="rnd">The System.Random to generate the numbers.</param>
 /// <returns>A standard normally distributed number.</returns>
 public static double Gaussian(this Random rnd)
 => GMath.Sqrt(-2 * GMath.Log(1.0 - rnd.NextDouble()));
예제 #23
0
 public Vector Component(Angle direction)
 => new Vector(X * GMath.Cos(direction) + Y * GMath.Sin(direction), direction);
예제 #24
0
 /// <summary>
 /// Returns a hash code for this GRaff.Line.
 /// </summary>
 /// <returns>An integer value that specifies a hash value for this GRaff.Line.</returns>
 public override int GetHashCode()
 => GMath.HashCombine(Origin.GetHashCode(), Offset.GetHashCode());
예제 #25
0
 /// <summary>
 /// Creates a GRaff.Matrix representing a rotation transform around the origin.
 /// </summary>
 /// <param name="a">The angle to rotate by.</param>
 /// <returns>A new GRaff.Matrix representing the transformation.</returns>
 public static Matrix Rotation(Angle a)
 => new Matrix(GMath.Cos(a), -GMath.Sin(a), 0, GMath.Sin(a), GMath.Cos(a), 0);
예제 #26
0
 public Angle Angle(Vector other)
 => GMath.Acos(UnitVector.Dot(other.UnitVector));