Blame mono/EllipseAntialiasing/MainWindow.cs

3d4d95
using System;
3d4d95
using System.Drawing;
3d4d95
using System.Drawing.Imaging;
3d4d95
using System.Windows.Forms;
3d4d95
using System.Collections.Generic;
3d4d95
3d4d95
namespace Faraday {
3d4d95
    public class MainWindow : Form {
3d4d95
        static public void Main() { Application.Run(new MainWindow()); }
3d4d95
3d4d95
		double tangentLength = 1000.0;
3d4d95
		double normalLength = 50.0;
3d4d95
		double pointRadius = 4.0;
3d4d95
3d4d95
		double targetX = 0.0;
3d4d95
		double targetY = 0.0;
3d4d95
3d4d95
		double aaRadius = 25.0;
3d4d95
		double radiusX = 400.0;
3d4d95
		double radiusY = 100.0;
3d4d95
3d4d95
		public MainWindow() {
3d4d95
            Paint += OnPaint;
3d4d95
			MouseMove += OnMouseMove;
3d4d95
            WindowState = FormWindowState.Maximized;
3d4d95
        }
3d4d95
3d4d95
        public void OnPaint(Object sender, PaintEventArgs e) {
3d4d95
            Draw(e.Graphics);
3d4d95
        }
3d4d95
3d4d95
        public void OnMouseMove(Object sender, MouseEventArgs e) {
3d4d95
			targetX = e.X - 0.5*ClientSize.Width;
3d4d95
			targetY = e.Y - 0.5*ClientSize.Height;
3d4d95
			Invalidate();
3d4d95
        }
3d4d95
3d4d95
        public void Draw(Graphics g) {
3d4d95
            g.Clear(Color.White);
3d4d95
			g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
3d4d95
3d4d95
			double centerX = 0.5*ClientSize.Width;
3d4d95
			double centerY = 0.5*ClientSize.Height;
3d4d95
3d4d95
			g.DrawEllipse(
3d4d95
				Pens.Gray,
3d4d95
				(float)(centerX - radiusX),
3d4d95
				(float)(centerY - radiusY),
3d4d95
				(float)(2.0*radiusX),
3d4d95
				(float)(2.0*radiusY));
3d4d95
3d4d95
			g.FillEllipse(
3d4d95
				Brushes.Blue,
3d4d95
				(float)(centerX + targetX - pointRadius),
3d4d95
				(float)(centerY + targetY - pointRadius),
3d4d95
				(float)(2.0*pointRadius),
3d4d95
				(float)(2.0*pointRadius));
3d4d95
3d4d95
			if (Math.Abs(targetX) > 0.0 || Math.Abs(targetY) > 0.0) {
3d4d95
				double targetL = Math.Sqrt(
3d4d95
					targetY*targetY +
3d4d95
					targetX*targetX);
3d4d95
				double targetNormX = targetX/targetL;
3d4d95
				double targetNormY = targetY/targetL;
3d4d95
3d4d95
				g.DrawLine(
3d4d95
					Pens.Black,
3d4d95
					(float)centerX,
3d4d95
					(float)centerY,
3d4d95
					(float)(centerX + tangentLength*targetNormX),
3d4d95
					(float)(centerY + tangentLength*targetNormY));
3d4d95
3d4d95
				double crossL = Math.Sqrt(
3d4d95
					targetY*targetY*radiusX*radiusX +
3d4d95
					targetX*targetX*radiusY*radiusY);
3d4d95
				double crossX = targetX*radiusX*radiusY/crossL;
3d4d95
				double crossY = targetY*radiusX*radiusY/crossL;
3d4d95
3d4d95
				g.FillEllipse(
3d4d95
					Brushes.Blue,
3d4d95
					(float)(centerX + crossX - pointRadius),
3d4d95
					(float)(centerY + crossY - pointRadius),
3d4d95
					(float)(2.0*pointRadius),
3d4d95
					(float)(2.0*pointRadius));
3d4d95
3d4d95
				double tangentL = Math.Sqrt(
3d4d95
					targetY*targetY*radiusX*radiusX*radiusX*radiusX +
3d4d95
					targetX*targetX*radiusY*radiusY*radiusY*radiusY);
3d4d95
				double tangentX = targetY*radiusX*radiusX/tangentL;
3d4d95
				double tangentY = -targetX*radiusY*radiusY/tangentL;
3d4d95
3d4d95
				g.DrawLine(
3d4d95
					Pens.Blue,
3d4d95
					(float)(centerX + crossX - tangentX*tangentLength),
3d4d95
					(float)(centerY + crossY - tangentY*tangentLength),
3d4d95
					(float)(centerX + crossX + tangentX*tangentLength),
3d4d95
					(float)(centerY + crossY + tangentY*tangentLength));
3d4d95
3d4d95
				double normalX = -tangentY;
3d4d95
				double normalY = tangentX;
3d4d95
3d4d95
				g.DrawLine(
3d4d95
					Pens.Blue,
3d4d95
					(float)(centerX + crossX),
3d4d95
					(float)(centerY + crossY),
3d4d95
					(float)(centerX + crossX + normalX*normalLength),
3d4d95
					(float)(centerY + crossY + normalY*normalLength));
3d4d95
3d4d95
				double dot = normalX*targetNormX + normalY*targetNormY;
3d4d95
				double aa = aaRadius/dot;
b1ff53
				//double aaX = aa*targetNormX;
b1ff53
				//double aaY = aa*targetNormY;
b1ff53
b1ff53
				double dotInv =
b1ff53
					tangentL/(targetX*targetX*radiusY*radiusY + targetY*targetY*radiusX*radiusX);
b1ff53
				double aaX = aaRadius*targetX*dotInv;
b1ff53
				double aaY = aaRadius*targetY*dotInv;
3d4d95
3d4d95
				g.DrawLine(
3d4d95
					Pens.Red,
b1ff53
					(float)(centerX + targetX - aaX),
b1ff53
					(float)(centerY + targetY - aaY),
b1ff53
					(float)(centerX + targetX + aaX),
b1ff53
					(float)(centerY + targetY + aaY));
3d4d95
				g.FillEllipse(
3d4d95
					Brushes.Red,
b1ff53
					(float)(centerX + targetX - aaX - pointRadius),
b1ff53
					(float)(centerY + targetY - aaY - pointRadius),
3d4d95
					(float)(2.0*pointRadius),
3d4d95
					(float)(2.0*pointRadius));
3d4d95
				g.FillEllipse(
3d4d95
					Brushes.Red,
b1ff53
					(float)(centerX + targetX + aaX - pointRadius),
b1ff53
					(float)(centerY + targetY + aaY - pointRadius),
3d4d95
					(float)(2.0*pointRadius),
3d4d95
					(float)(2.0*pointRadius));
3d4d95
			}
3d4d95
        }
3d4d95
    }
3d4d95
}
3d4d95