using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
using Nuclex.Geometry.Areas;
namespace Nuclex.Geometry.Demo {
/// Form that demonstrates the random point generation algorithms
public partial class RandomPointDemoForm : Form {
#region class Area2Painter
#if false
/// Paints any IArea2 based shape into a graphics context
private class Area2Painter : IArea2Visitor {
/// Initializes a new IArea2 painter
/// Graphics context the painter will paint into
/// Size of the drawing region
public Area2Painter(Graphics graphics, SizeF size) {
this.size = size;
this.graphics = graphics;
}
/// Paints the provided shape
/// Shape that will be painted
public void Paint(IArea2 shape) {
shape.Accept(this);
}
/// Visits an axis aligned rectangle to paint it
/// Rectangle that will be painted
void IArea2Visitor.Visit(AxisAlignedRectangle2 rectangle) {
this.graphics.DrawRectangle(
Pens.Black,
rectangle.Min.X * this.size.Width,
rectangle.Min.Y * this.size.Height,
(rectangle.Max.X - rectangle.Min.X) * this.size.Width,
(rectangle.Max.Y - rectangle.Min.Y) * this.size.Height
);
}
/// Visits an axis aligned rectangle to paint it
/// Rectangle that will be painted
void IArea2Visitor.Visit(Rectangle2 rectangle) {
// Not supported yet...
}
/// Visits a triangle to paint it
/// Triangle that will be painted
void IArea2Visitor.Visit(Triangle2 triangle) {
this.graphics.DrawLines(
Pens.Black,
new PointF[] {
new PointF(
triangle.A.X * this.size.Width,
triangle.A.Y * this.size.Height
),
new PointF(
triangle.B.X * this.size.Width,
triangle.B.Y * this.size.Height
),
new PointF(
triangle.C.X * this.size.Width,
triangle.C.Y * this.size.Height
),
new PointF(
triangle.A.X * this.size.Width,
triangle.A.Y * this.size.Height
)
}
);
}
/// Visits a disc to paint it
/// Disc that will be painted
void IArea2Visitor.Visit(Disc2 disc) {
float radiusX = disc.Radius * this.size.Width;
float radiusY = disc.Radius * this.size.Height;
this.graphics.DrawEllipse(
Pens.Black,
disc.Center.X * this.size.Width - radiusX,
disc.Center.Y * this.size.Height - radiusY,
radiusX * 2.0f,
radiusY * 2.0f
);
}
/// Graphics context drawing will take place in
private Graphics graphics;
/// Size of the drawing area
private SizeF size;
}
#endif
#endregion // class Area2Painter
/// Initializes a new random point demonstration form
public RandomPointDemoForm() {
InitializeComponent();
}
/// Switches to the rectangle shape when its option is selected
/// Option that has been selected
/// Not used
private void rectangleSelected(object sender, EventArgs e) {
this.activeShape = new AxisAlignedRectangle2(
new Vector2(0.1f, 0.1f), new Vector2(0.9f, 0.9f)
);
this.demoPicture.Refresh();
}
/// Switches to the triangle shape when its option is selected
/// Option that has been selected
/// Not used
private void triangleSelected(object sender, EventArgs e) {
this.activeShape = new Triangle2(
new Vector2(0.1f, 0.1f), new Vector2(0.9f, 0.1f), new Vector2(0.5f, 0.9f)
);
this.demoPicture.Refresh();
}
/// Switches to the disc shape when its option is selected
/// Option that has been selected
/// Not used
private void discSelected(object sender, EventArgs e) {
this.activeShape = new Disc2(
new Vector2(0.5f, 0.5f), 0.4f
);
this.demoPicture.Refresh();
}
/// Called when the demo picture is painting itself
/// Picture that is painting itself
/// Contains the graphics context to paint in
private void demoPicturePainting(object sender, PaintEventArgs e) {
#if false
// Store the size of the drawing area in floating point coordinates
SizeF size = new SizeF(
(float)this.demoPicture.Width, (float)this.demoPicture.Height
);
// If a shape has been selected, draw it into the drawing area
if(this.activeShape != null)
new Area2Painter(e.Graphics, size).Paint(this.activeShape);
// If points have been generated, draw the points as well
if(this.points != null) {
foreach(Vector2 point in this.points) {
e.Graphics.FillEllipse(
Brushes.DarkGray,
point.X * size.Width - 1.0f,
point.Y * size.Height - 1.0f,
3.0f,
3.0f
);
}
}
#endif
}
/// Generates a number of random points inside or on the shape
/// Button that has been clicked
/// Not used
private void generateClicked(object sender, EventArgs e) {
if(this.activeShape != null) {
DefaultRandom rng = new DefaultRandom();
const int PointCount = 1000;
this.points = new Vector2[PointCount];
if(this.perimeterOption.Checked) {
for(int point = 0; point < PointCount; ++point)
this.points[point] = this.activeShape.RandomPointOnPerimeter(rng);
} else {
for(int point = 0; point < PointCount; ++point)
this.points[point] = this.activeShape.RandomPointWithin(rng);
}
this.demoPicture.Refresh();
}
}
/// The currently active shape, selected by the user
private IArea2 activeShape;
///
/// Points that have been generated when the 'Generate' button was clicked
///
private Vector2[] points;
}
} // namespace Nuclex.Geometry.Demo