/// <summary> /// Determines if an ellipse and a rectangle intersect. /// </summary> /// <param name="ellipse">The ellipse.</param> /// <param name="rectangle">The rectangle.</param> /// <returns></returns> public static bool EllipseRectangleTest(Ellipse ellipse, OrthoRectangle rectangle) { bool testXpos = (ellipse.Center.X + ellipse.RadiusX) > rectangle.Right; bool testXneg = (ellipse.Center.X - ellipse.RadiusX) < rectangle.Left; bool testYpos = (ellipse.Center.Y + ellipse.RadiusY) > rectangle.Top; bool testYneg = (ellipse.Center.Y - ellipse.RadiusY) < rectangle.Bottom; return testXpos || testXneg || testYpos || testYneg; }
/// <summary> /// Determines whether a circle and a rectangle intersect. /// </summary> /// <param name="circle">The circle.</param> /// <param name="rectangle">The rectangle.</param> /// <returns>True if the circle and rectangle intersect or collide.</returns> public static bool CircleRectangleTest(Circle circle, OrthoRectangle rectangle) { Vector2D circleDistance = new Vector2D(Math.Abs(circle.Center.X - rectangle.X - rectangle.Width / 2), Math.Abs(circle.Center.Y - rectangle.Y - rectangle.Height / 2)); if (circleDistance.X > (rectangle.Width / 2 + circle.Radius)) return false; if (circleDistance.Y > (rectangle.Height / 2 + circle.Radius)) return false; if (circleDistance.X <= (rectangle.Width / 2)) return true; if (circleDistance.Y <= (rectangle.Height / 2)) return true; double cornerDistanceSquared = Math.Pow(circleDistance.X - rectangle.Width / 2, 2) + Math.Pow(circleDistance.Y - rectangle.Height / 2, 2); return (cornerDistanceSquared <= (Math.Pow(circle.Radius, 2))); }
public static bool IsPointInside(OrthoRectangle bounds, Borders edge, Vector2D p) { switch (edge) { case Borders.Left: return !(p.X <= bounds.Left); case Borders.Right: return !(p.X >= bounds.Right); case Borders.Top: return !(p.Y >= bounds.Top); case Borders.Bottom: return !(p.Y <= bounds.Bottom); default: throw Error.WrongCase("edge", "IsPointInside", edge); } }
public Ellipse CreateEllipse(OrthoRectangle rectangle) { Vector2D radialCenter = new Vector2D(rectangle.TopLeft.X + Center.X * rectangle.Width, rectangle.TopLeft.Y - Center.Y * rectangle.Height); return new Ellipse(radialCenter, RadiusX * rectangle.Width, RadiusY * rectangle.Height); }
public static bool EllipseContainsRectangle(Ellipse ellipse, OrthoRectangle rectangle) { Vector2D[] vertices = rectangle.VerticesArray; return vertices.All(v => EllipsePointTest(ellipse, v)); }
public static bool RectangleContainsEllipse(OrthoRectangle rectangle, Ellipse ellipse) { bool testXpos = (ellipse.Center.X + ellipse.RadiusX) < rectangle.Right; bool testXneg = (ellipse.Center.X - ellipse.RadiusX) > rectangle.Left; bool testYpos = (ellipse.Center.Y + ellipse.RadiusY) < rectangle.Top; bool testYneg = (ellipse.Center.Y - ellipse.RadiusY) > rectangle.Bottom; return testXpos && testXneg && testYpos && testYneg; }
public void DrawClippedEllipse() { CheckParameters(Options.Size | Options.Shader); RadialShader rs = (RadialShader) Shader; // Create a polygon for the control bounds OrthoRectangle rectangle = new OrthoRectangle(Position.X, Position.Y, Width, Height); // Create the ellipse representing the radial effect Ellipse ellipse = rs.CreateEllipse(rectangle); // Create the ellipse polygon for the radial gradient PolyEllipse ellipsePolygon = PolyEllipse.CreateEllipse(ellipse, EllipseSegments); Polygon rectanglePolygon = (Polygon) rectangle; //rectanglePolygon.Detail(16); float[] offsets = Shader.Gradient.Skip(1).Select(g => g.Offset).ToArray(); // Determine if we need to clip the inner ellipses int innerSegments = DetermineEllipsesToClip(ellipse, rectangle, offsets); Ellipse[] ellipses = (from f in offsets select new Ellipse(ellipse.Center, f*ellipse.RadiusX, f*ellipse.RadiusY)).ToArray(); GradientStop[] gradient = rs.Gradient; List<Vector2D> points = new List<Vector2D>(); //List<Polygon> clipResult = new List<Polygon>(); PolyClipError polyClipError; //if (innerSegments < ellipses.Length) //{ PolyEllipse outerEllipse = PolyEllipse.CreateEllipse(ellipse, rs.Slices, offsets); //EllipseClipper.ClipAgainstPolygon(outerEllipse, rectanglePolygon); for (int i = 0; i < outerEllipse.Slices; i++) { Polygon ringSlice = outerEllipse.GetRingSlice(i, 0, 3); Polygon clipResult = YuPengClipper.Intersect(ringSlice, rectanglePolygon, out polyClipError)[0]; points.AddRange(clipResult.Vertices); } //} //if (innerSegments < ellipses.Length) //{ // for (int i = innerSegments; i < ellipses.Length; i++) // { // PolyEllipse firstClippedEllipse = PolyEllipse.CreateEllipse(ellipses[i], rs.Slices); // Polygon clippedAgainstRectangle = // YuPengClipper.Intersect(firstClippedEllipse, rectanglePolygon, out polyClipError)[0]; // points.AddRange(clippedAgainstRectangle.Vertices); // } // for (int i = 0; i < innerSegments; i++) // { // PolyEllipse innerEllipse = PolyEllipse.CreateEllipse(ellipses[i], rs.Slices); // points.AddRange(innerEllipse.Vertices); // } //points.Insert(0, ellipse.Center); ushort[] indices = Delauney.Triangulate(points); Color4[] colors = RadialShader.RadialManual2(gradient, points.Count, points, ellipse); ShapeDescription ellipseShape = new ShapeDescription { Vertices = points.Select( (v, index) => new ColoredVertex(new Vector4(v, Position.Z, 1.0f), colors[index])).ToArray(), Indices = indices, Primitives = indices.Length / 3, Shape = Shape.RectangleMesh }; shapes.Add(ellipseShape); //} //if (innerSegments != 0) //{ // rs.Gradient = SplitGradient(gradient, 0, innerSegments); // DrawEllipse(ellipses[innerSegments - 1]); // rs.Gradient = gradient; //} }
private int DetermineEllipsesToClip(Ellipse outer, OrthoRectangle rectangle, float[] segmentOffsets) { int segments = 0; for (int i = 0; i < segmentOffsets.Length; i++) { float offset = segmentOffsets[i]; double radiusX = outer.RadiusX*offset; double radiusY = outer.RadiusY*offset; Ellipse inner = new Ellipse(outer.Center, radiusX, radiusY); if (Intersection.RectangleContainsEllipse(rectangle, inner)) segments++; } return segments; }
static ShapeDescription DrawRectangle(BaseControl control) { ControlDescription desc = control.Description; Designer d = control.GetDesigner(); d.Position = control.AbsoluteOrthoPosition; foreach (BorderShader borderShader in desc.BorderShaders) { d.BorderSize = borderShader.Borders != Borders.All ? MaskBorderSize(borderShader.Borders, desc.BorderSize) : desc.BorderSize; d.Shader = borderShader; d.DrawRectangle(); } d.Position = new Vector3 (d.Position.X + desc.BorderSize.Left, d.Position.Y - desc.BorderSize.Top, d.Position.Z); d.Width = control.ClientSize.Width; d.Height = control.ClientSize.Height; foreach (IGradientShader colorShader in desc.Enabled) { switch (colorShader.GradientType) { default: d.Shader = colorShader; d.FillRectangle(); break; case GradientType.Radial: RadialShader rs = (RadialShader)colorShader; //// First draw background color from the radial shader's outermost color //d.Shader = LinearShader.CreateUniform(rs.Gradient[rs.Gradient.Length - 1].Color); //d.FillRectangle(); d.Shader = rs; OrthoRectangle rectangle = new OrthoRectangle(d.Position.X, d.Position.Y, d.Width, d.Height); bool test = Intersection.EllipseRectangleTest(rs.CreateEllipse(rectangle), rectangle); if (!test) d.DrawEllipse(); else d.DrawClippedEllipse(); break; } } //d.Vertices = new Vector4[] { d.Position.ToVector4(), d.Position.ToVector4() + new Vector4(50, -50f, 0, 1.0f), // d.Position.ToVector4() + new Vector4(75, 200, 0, 1.0f) }; return d.Output; }