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