# 对专机2部6轴平台支持,修改HexalMC

This commit is contained in:
zhengxuan.zhang
2025-03-29 16:20:59 +08:00
parent 9f3ee84467
commit 6ad8cfcd14
37 changed files with 8287 additions and 8278 deletions
+86 -91
View File
@@ -1,105 +1,100 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Scatter
{
static class Algerbra
{
public class Matrix<T>
{
int rows;
int columns;
internal static class Algerbra
{
public class Matrix<T>
{
private int rows;
private int columns;
private T[,] matrix;
private T[,] matrix;
public Matrix(int n, int m)
{
matrix = new T[n, m];
rows = n;
columns = m;
}
public Matrix(int n, int m)
{
matrix = new T[n, m];
rows = n;
columns = m;
}
public void SetValByIdx(int m, int n, T x)
{
matrix[n, m] = x;
}
public void SetValByIdx(int m, int n, T x)
{
matrix[n, m] = x;
}
public T GetValByIndex(int n, int m)
{
return matrix[n, m];
}
public T GetValByIndex(int n, int m)
{
return matrix[n, m];
}
public void SetMatrix(T[] arr)
{
for (int r = 0; r < rows; r++)
for (int c = 0; c < columns; c++)
matrix[r, c] = arr[r * columns + c];
}
public void SetMatrix(T[] arr)
{
for (int r = 0; r < rows; r++)
for (int c = 0; c < columns; c++)
matrix[r, c] = arr[r * columns + c];
}
public static Matrix<T> operator |(Matrix<T> m1, Matrix<T> m2)
{
Matrix<T> m = new Matrix<T>(m1.rows, m1.columns + m2.columns);
for (int r = 0; r < m1.rows; r++)
{
for (int c = 0; c < m1.columns; c++)
m.matrix[r, c] = m1.matrix[r, c];
for (int c = 0; c < m2.columns; c++)
m.matrix[r, c + m1.columns] = m2.matrix[r, c];
}
return m;
}
public static Matrix<T> operator |(Matrix<T> m1, Matrix<T> m2)
{
Matrix<T> m = new Matrix<T>(m1.rows, m1.columns + m2.columns);
for (int r = 0; r < m1.rows; r++)
{
for (int c = 0; c < m1.columns; c++)
m.matrix[r, c] = m1.matrix[r, c];
for (int c = 0; c < m2.columns; c++)
m.matrix[r, c + m1.columns] = m2.matrix[r, c];
}
return m;
}
public static Matrix<T> operator *(Matrix<T> m1, Matrix<T> m2)
{
Matrix<T> m = new Matrix<T>(m1.rows, m2.columns);
for (int r = 0; r < m.rows; r++)
for (int c = 0; c < m.columns; c++)
{
T tmp = (dynamic)0;
for (int i = 0; i < m2.rows; i++)
tmp += (dynamic)m1.matrix[r, i] * (dynamic)m2.matrix[i, c];
m.matrix[r, c] = tmp;
}
return m;
}
public static Matrix<T> operator *(Matrix<T> m1, Matrix<T> m2)
{
Matrix<T> m = new Matrix<T>(m1.rows, m2.columns);
for (int r = 0; r < m.rows; r++)
for (int c = 0; c < m.columns; c++)
{
T tmp = (dynamic)0;
for (int i = 0; i < m2.rows; i++)
tmp += (dynamic)m1.matrix[r, i] * (dynamic)m2.matrix[i, c];
m.matrix[r, c] = tmp;
}
return m;
}
public static Matrix<T> operator ~(Matrix<T> m)
{
Matrix<T> tmp = new Matrix<T>(m.columns, m.rows);
for (int r = 0; r < m.rows; r++)
for (int c = 0; c < m.columns; c++)
tmp.matrix[c, r] = m.matrix[r, c];
return tmp;
}
public static Matrix<T> operator ~(Matrix<T> m)
{
Matrix<T> tmp = new Matrix<T>(m.columns, m.rows);
for (int r = 0; r < m.rows; r++)
for (int c = 0; c < m.columns; c++)
tmp.matrix[c, r] = m.matrix[r, c];
return tmp;
}
public static Matrix<T> operator -(Matrix<T> m)
{
Matrix<T> tmp = new Matrix<T>(m.columns, m.rows);
for (int r = 0; r < m.rows; r++)
for (int c = 0; c < m.columns; c++)
tmp.matrix[r, c] = -(dynamic)m.matrix[r, c];
return tmp;
}
public static Matrix<T> operator -(Matrix<T> m)
{
Matrix<T> tmp = new Matrix<T>(m.columns, m.rows);
for (int r = 0; r < m.rows; r++)
for (int c = 0; c < m.columns; c++)
tmp.matrix[r, c] = -(dynamic)m.matrix[r, c];
return tmp;
}
public override string ToString()
{
String output = "";
for (int r = 0; r < rows; r++)
{
output += "[\t";
for (int c = 0; c < columns; c++)
{
output += matrix[r, c].ToString();
if (c < columns - 1) output += ",\t";
}
output += "]\n";
}
return output;
}
}
}
}
public override string ToString()
{
String output = "";
for (int r = 0; r < rows; r++)
{
output += "[\t";
for (int c = 0; c < columns; c++)
{
output += matrix[r, c].ToString();
if (c < columns - 1) output += ",\t";
}
output += "]\n";
}
return output;
}
}
}
}
+51 -54
View File
@@ -1,68 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Windows.Forms;
namespace Scatter
{
public static class MouseWheelHandler
{
public static void Add(Control ctrl, Action<MouseEventArgs> onMouseWheel)
{
if (ctrl == null || onMouseWheel == null)
throw new ArgumentNullException();
public static class MouseWheelHandler
{
public static void Add(Control ctrl, Action<MouseEventArgs> onMouseWheel)
{
if (ctrl == null || onMouseWheel == null)
throw new ArgumentNullException();
var filter = new MouseWheelMessageFilter(ctrl, onMouseWheel);
Application.AddMessageFilter(filter);
ctrl.Disposed += (s, e) => Application.RemoveMessageFilter(filter);
}
var filter = new MouseWheelMessageFilter(ctrl, onMouseWheel);
Application.AddMessageFilter(filter);
ctrl.Disposed += (s, e) => Application.RemoveMessageFilter(filter);
}
class MouseWheelMessageFilter
: IMessageFilter
{
private readonly Control _ctrl;
private readonly Action<MouseEventArgs> _onMouseWheel;
private class MouseWheelMessageFilter
: IMessageFilter
{
private readonly Control _ctrl;
private readonly Action<MouseEventArgs> _onMouseWheel;
public MouseWheelMessageFilter(Control ctrl, Action<MouseEventArgs> onMouseWheel)
{
_ctrl = ctrl;
_onMouseWheel = onMouseWheel;
}
public MouseWheelMessageFilter(Control ctrl, Action<MouseEventArgs> onMouseWheel)
{
_ctrl = ctrl;
_onMouseWheel = onMouseWheel;
}
public bool PreFilterMessage(ref Message m)
{
var parent = _ctrl.Parent;
if (parent != null && m.Msg == 0x20a) // WM_MOUSEWHEEL, find the control at screen position m.LParam
{
var pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
public bool PreFilterMessage(ref Message m)
{
var parent = _ctrl.Parent;
if (parent != null && m.Msg == 0x20a) // WM_MOUSEWHEEL, find the control at screen position m.LParam
{
var pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
var clientPos = _ctrl.PointToClient(pos);
var clientPos = _ctrl.PointToClient(pos);
if (_ctrl.ClientRectangle.Contains(clientPos)
&& ReferenceEquals(_ctrl, parent.GetChildAtPoint(parent.PointToClient(pos))))
{
var wParam = m.WParam.ToInt32();
Func<int, MouseButtons, MouseButtons> getButton =
(flag, button) => ((wParam & flag) == flag) ? button : MouseButtons.None;
if (_ctrl.ClientRectangle.Contains(clientPos)
&& ReferenceEquals(_ctrl, parent.GetChildAtPoint(parent.PointToClient(pos))))
{
var wParam = m.WParam.ToInt32();
Func<int, MouseButtons, MouseButtons> getButton =
(flag, button) => ((wParam & flag) == flag) ? button : MouseButtons.None;
var buttons = getButton(wParam & 0x0001, MouseButtons.Left)
| getButton(wParam & 0x0010, MouseButtons.Middle)
| getButton(wParam & 0x0002, MouseButtons.Right)
| getButton(wParam & 0x0020, MouseButtons.XButton1)
| getButton(wParam & 0x0040, MouseButtons.XButton2)
; // Not matching for these /*MK_SHIFT=0x0004;MK_CONTROL=0x0008*/
var buttons = getButton(wParam & 0x0001, MouseButtons.Left)
| getButton(wParam & 0x0010, MouseButtons.Middle)
| getButton(wParam & 0x0002, MouseButtons.Right)
| getButton(wParam & 0x0020, MouseButtons.XButton1)
| getButton(wParam & 0x0040, MouseButtons.XButton2)
; // Not matching for these /*MK_SHIFT=0x0004;MK_CONTROL=0x0008*/
var delta = wParam >> 16;
var e = new MouseEventArgs(buttons, 0, clientPos.X, clientPos.Y, delta);
_onMouseWheel(e);
var delta = wParam >> 16;
var e = new MouseEventArgs(buttons, 0, clientPos.X, clientPos.Y, delta);
_onMouseWheel(e);
return true;
}
}
return false;
}
}
}
}
return true;
}
}
return false;
}
}
}
}
+53 -56
View File
@@ -1,67 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Diagnostics;
namespace Scatter
{
static class Projection
{
static public PointF Project(double[] x, double s_x, double s_y, double f, double[] d_w, double azimuth, double elevation)
{
Algerbra.Matrix<double> Mext = GetMext(azimuth, elevation, d_w);
Algerbra.Matrix<double> Mint = GetMint(s_x, s_y, f);
Algerbra.Matrix<double> X_h = new Algerbra.Matrix<double>(4, 1);
X_h.SetMatrix(new double[] { x[0], x[1], x[2], 1.0});
//Debug.Print((Mint * Mext).ToString());
Algerbra.Matrix<double> P = Mint * Mext * X_h;
return new PointF((float)(P.GetValByIndex(0, 0) / P.GetValByIndex(2, 0)), (float)(P.GetValByIndex(1, 0) / P.GetValByIndex(2, 0)));
}
internal static class Projection
{
public static PointF Project(double[] x, double s_x, double s_y, double f, double[] d_w, double azimuth, double elevation)
{
Algerbra.Matrix<double> Mext = GetMext(azimuth, elevation, d_w);
Algerbra.Matrix<double> Mint = GetMint(s_x, s_y, f);
Algerbra.Matrix<double> X_h = new Algerbra.Matrix<double>(4, 1);
X_h.SetMatrix(new double[] { x[0], x[1], x[2], 1.0 });
//Debug.Print((Mint * Mext).ToString());
Algerbra.Matrix<double> P = Mint * Mext * X_h;
return new PointF((float)(P.GetValByIndex(0, 0) / P.GetValByIndex(2, 0)), (float)(P.GetValByIndex(1, 0) / P.GetValByIndex(2, 0)));
}
static public PointF[] ProjectVector(List<double[]> x, double s_x, double s_y, double f, double[] d_w, double azimuth, double elevation)
{
Algerbra.Matrix<double> Mext = GetMext(azimuth, elevation, d_w);
Algerbra.Matrix<double> Mint = GetMint(s_x, s_y, f);
Algerbra.Matrix<double> X_h = new Algerbra.Matrix<double>(4, 1);
public static PointF[] ProjectVector(List<double[]> x, double s_x, double s_y, double f, double[] d_w, double azimuth, double elevation)
{
Algerbra.Matrix<double> Mext = GetMext(azimuth, elevation, d_w);
Algerbra.Matrix<double> Mint = GetMint(s_x, s_y, f);
Algerbra.Matrix<double> X_h = new Algerbra.Matrix<double>(4, 1);
PointF[] Pvec = new PointF[x.Count];
for (int i = 0; i < x.Count; i++)
{
X_h.SetMatrix(new double[] { x[i][0], x[i][1], x[i][2], 1.0 });
Algerbra.Matrix<double> P = Mint * Mext * X_h;
Pvec[i] = new PointF((float)(P.GetValByIndex(0, 0) / P.GetValByIndex(2, 0)), (float)(P.GetValByIndex(1, 0) / P.GetValByIndex(2, 0)));
}
return Pvec;
}
PointF[] Pvec = new PointF[x.Count];
for (int i = 0; i < x.Count; i++)
{
X_h.SetMatrix(new double[] { x[i][0], x[i][1], x[i][2], 1.0 });
Algerbra.Matrix<double> P = Mint * Mext * X_h;
Pvec[i] = new PointF((float)(P.GetValByIndex(0, 0) / P.GetValByIndex(2, 0)), (float)(P.GetValByIndex(1, 0) / P.GetValByIndex(2, 0)));
}
return Pvec;
}
static Algerbra.Matrix<double> GetMint(double s_x, double s_y, double f)
{
Algerbra.Matrix<double> Mint = new Algerbra.Matrix<double>(3, 3);
double o_x = s_x / 2;
double o_y = s_y / 2;
double a = 1;
Mint.SetMatrix(new double[] { f, 0, o_x, 0, f * a, o_y, 0, 0, 1 });
return Mint;
}
private static Algerbra.Matrix<double> GetMint(double s_x, double s_y, double f)
{
Algerbra.Matrix<double> Mint = new Algerbra.Matrix<double>(3, 3);
double o_x = s_x / 2;
double o_y = s_y / 2;
double a = 1;
Mint.SetMatrix(new double[] { f, 0, o_x, 0, f * a, o_y, 0, 0, 1 });
return Mint;
}
static Algerbra.Matrix<double> GetMext(double azimuth, double elevation, double[] d_w)
{
Algerbra.Matrix<double> R = RotationMatrix(azimuth, elevation);
Algerbra.Matrix<double> dw = new Algerbra.Matrix<double>(3, 1);
dw.SetMatrix(d_w);
Algerbra.Matrix<double> Mext = R | (-R * dw);
return Mext;
}
private static Algerbra.Matrix<double> GetMext(double azimuth, double elevation, double[] d_w)
{
Algerbra.Matrix<double> R = RotationMatrix(azimuth, elevation);
Algerbra.Matrix<double> dw = new Algerbra.Matrix<double>(3, 1);
dw.SetMatrix(d_w);
Algerbra.Matrix<double> Mext = R | (-R * dw);
return Mext;
}
static Algerbra.Matrix<double> RotationMatrix(double azimuth, double elevation)
{
Algerbra.Matrix<double> R = new Algerbra.Matrix<double>(3, 3);
R.SetMatrix(new double[] { Math.Cos(azimuth), 0, -Math.Sin(azimuth),
Math.Sin(azimuth)*Math.Sin(elevation), Math.Cos(elevation), Math.Cos(azimuth)*Math.Sin(elevation),
Math.Cos(elevation)*Math.Sin(azimuth), -Math.Sin(elevation), Math.Cos(azimuth)*Math.Cos(elevation) });
return R;
}
}
}
private static Algerbra.Matrix<double> RotationMatrix(double azimuth, double elevation)
{
Algerbra.Matrix<double> R = new Algerbra.Matrix<double>(3, 3);
R.SetMatrix(new double[] { Math.Cos(azimuth), 0, -Math.Sin(azimuth),
Math.Sin(azimuth)*Math.Sin(elevation), Math.Cos(elevation), Math.Cos(azimuth)*Math.Sin(elevation),
Math.Cos(elevation)*Math.Sin(azimuth), -Math.Sin(elevation), Math.Cos(azimuth)*Math.Cos(elevation) });
return R;
}
}
}
+143 -151
View File
@@ -1,179 +1,171 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
namespace Scatter
{
public partial class ScatterPlot : UserControl
{
List<List<double[]>> Points = new List<List<double[]>>();
List<PointF[]> ProjPoints = new List<PointF[]>();
private double f = 1000;
private double d = 5;
private double[] d_w = new double[3];
private double last_azimuth, azimuth = 0, last_elevation, elevation = 0;
private bool leftMousePressed = false;
private PointF ptMouseClick;
public partial class ScatterPlot : UserControl
{
private List<List<double[]>> Points = new List<List<double[]>>();
private List<PointF[]> ProjPoints = new List<PointF[]>();
private double f = 1000;
private double d = 5;
private double[] d_w = new double[3];
private double last_azimuth, azimuth = 0, last_elevation, elevation = 0;
private bool leftMousePressed = false;
private PointF ptMouseClick;
public double Distance
{
get { return d; }
set { d = (value >= 0.1) ? d = value : d; UpdateProjection(); }
}
public double Distance
{
get { return d; }
set { d = (value >= 0.1) ? d = value : d; UpdateProjection(); }
}
public double F
{
get { return f; }
set { f = value; UpdateProjection(); }
}
public double F
{
get { return f; }
set { f = value; UpdateProjection(); }
}
public double[] CameraPos
{
get { return d_w;}
set { d_w = value; UpdateProjection(); }
}
public double[] CameraPos
{
get { return d_w; }
set { d_w = value; UpdateProjection(); }
}
public double Azimuth
{
get { return azimuth; }
set { azimuth = value; UpdateProjection(); }
}
public double Elevation
{
get { return elevation; }
set { elevation = value; UpdateProjection(); }
}
public double Azimuth
{
get { return azimuth; }
set { azimuth = value; UpdateProjection(); }
}
public ScatterPlot()
{
InitializeComponent();
MouseWheelHandler.Add(this, MyOnMouseWheel);
}
public double Elevation
{
get { return elevation; }
set { elevation = value; UpdateProjection(); }
}
protected override CreateParams CreateParams
{
get
{
var cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
public ScatterPlot()
{
InitializeComponent();
MouseWheelHandler.Add(this, MyOnMouseWheel);
}
Color[] colorIdx = new Color[] { Color.Blue, Color.Red, Color.Green, Color.Orange, Color.Fuchsia, Color.Black };
protected override CreateParams CreateParams
{
get
{
var cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
private Color[] colorIdx = new Color[] { Color.Blue, Color.Red, Color.Green, Color.Orange, Color.Fuchsia, Color.Black };
Graphics g = this.CreateGraphics();
g.FillRectangle(Brushes.White, new Rectangle(0, 0, this.Width, this.Height));
if (ProjPoints != null)
{
for (int i = 0; i < ProjPoints.Count; i++)
{
foreach (PointF p in ProjPoints[i])
{
g.FillEllipse(new SolidBrush(colorIdx[i % colorIdx.Length]), new RectangleF(p.X, p.Y, 4, 4));
}
}
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
public void AddPoint(double x, double y, double z, int series)
{
if (Points.Count - 1 < series)
{
Points.Add(new List<double[]>());
}
Graphics g = this.CreateGraphics();
g.FillRectangle(Brushes.White, new Rectangle(0, 0, this.Width, this.Height));
if (ProjPoints != null)
{
for (int i = 0; i < ProjPoints.Count; i++)
{
foreach (PointF p in ProjPoints[i])
{
g.FillEllipse(new SolidBrush(colorIdx[i % colorIdx.Length]), new RectangleF(p.X, p.Y, 4, 4));
}
}
}
}
Points[series].Add(new double[] { x, y, z });
public void AddPoint(double x, double y, double z, int series)
{
if (Points.Count - 1 < series)
{
Points.Add(new List<double[]>());
}
foreach (List<double[]> ser in Points)
{
if (ProjPoints.Count - 1 < series)
ProjPoints.Add(Projection.ProjectVector(ser, this.Width, this.Height, f, d_w, azimuth, elevation));
else
ProjPoints[series] = Projection.ProjectVector(ser, this.Width, this.Height, f, d_w, azimuth, elevation);
}
this.Invalidate();
}
Points[series].Add(new double[] { x, y, z });
public void AddPoints(List<double[]> points)
{
List<double[]> _tmp = new List<double[]>(points);
Points.Add(_tmp);
ProjPoints.Add(Projection.ProjectVector(Points[Points.Count-1], this.Width, this.Height, f, d_w, azimuth, elevation));
UpdateProjection();
}
foreach (List<double[]> ser in Points)
{
if (ProjPoints.Count - 1 < series)
ProjPoints.Add(Projection.ProjectVector(ser, this.Width, this.Height, f, d_w, azimuth, elevation));
else
ProjPoints[series] = Projection.ProjectVector(ser, this.Width, this.Height, f, d_w, azimuth, elevation);
}
this.Invalidate();
}
public void Clear()
{
ProjPoints.Clear();
Points.Clear();
Azimuth = 0;
Elevation = 0;
}
public void AddPoints(List<double[]> points)
{
List<double[]> _tmp = new List<double[]>(points);
Points.Add(_tmp);
ProjPoints.Add(Projection.ProjectVector(Points[Points.Count - 1], this.Width, this.Height, f, d_w, azimuth, elevation));
UpdateProjection();
}
private void ScatterPlot_MouseMove(object sender, MouseEventArgs e)
{
if (leftMousePressed)
{
azimuth = last_azimuth - (ptMouseClick.X - e.X) / 100;
elevation = last_elevation + (ptMouseClick.Y - e.Y) / 100;
UpdateProjection();
}
}
public void Clear()
{
ProjPoints.Clear();
Points.Clear();
Azimuth = 0;
Elevation = 0;
}
private void ScatterPlot_SizeChanged(object sender, EventArgs e)
{
if (ProjPoints != null)
UpdateProjection();
}
private void ScatterPlot_MouseMove(object sender, MouseEventArgs e)
{
if (leftMousePressed)
{
azimuth = last_azimuth - (ptMouseClick.X - e.X) / 100;
elevation = last_elevation + (ptMouseClick.Y - e.Y) / 100;
UpdateProjection();
}
}
private void ScatterPlot_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
leftMousePressed = true;
ptMouseClick = new PointF(e.X, e.Y);
last_azimuth = azimuth;
last_elevation = elevation;
}
}
private void ScatterPlot_SizeChanged(object sender, EventArgs e)
{
if (ProjPoints != null)
UpdateProjection();
}
private void ScatterPlot_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
leftMousePressed = false;
}
private void ScatterPlot_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
leftMousePressed = true;
ptMouseClick = new PointF(e.X, e.Y);
last_azimuth = azimuth;
last_elevation = elevation;
}
}
private void MyOnMouseWheel(MouseEventArgs e)
{
Distance += -e.Delta / 500D;
}
private void ScatterPlot_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
leftMousePressed = false;
}
private void UpdateProjection()
{
if (ProjPoints == null)
return;
double x = d * Math.Cos(elevation) * Math.Cos(azimuth);
double y = d * Math.Cos(elevation) * Math.Sin(azimuth);
double z = d * Math.Sin(elevation);
d_w = new double[3] { -y, z, -x };
for (int i = 0; i < ProjPoints.Count; i++)
ProjPoints[i] = Projection.ProjectVector(Points[i], this.Width, this.Height, f, d_w, azimuth, elevation);
this.Invalidate();
}
private void MyOnMouseWheel(MouseEventArgs e)
{
Distance += -e.Delta / 500D;
}
}
}
private void UpdateProjection()
{
if (ProjPoints == null)
return;
double x = d * Math.Cos(elevation) * Math.Cos(azimuth);
double y = d * Math.Cos(elevation) * Math.Sin(azimuth);
double z = d * Math.Sin(elevation);
d_w = new double[3] { -y, z, -x };
for (int i = 0; i < ProjPoints.Count; i++)
ProjPoints[i] = Projection.ProjectVector(Points[i], this.Width, this.Height, f, d_w, azimuth, elevation);
this.Invalidate();
}
}
}