|
|
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 |
|