WPF-Helixtoolkit绘制螺旋路径
视频演示
部分代码:
一、绘制螺旋线
private void GatherData(object sender, DoWorkEventArgs e)
{
while (true)
{
//Thread.Sleep(5); // 50ms数据采样周期
// Generate a test trace: an upward spiral with square corners
//生成一个测试轨迹:一个带有方角的向上螺旋线
double t = stopwatch.Elapsed.TotalSeconds * 1;//* 0.25;
double sint = Math.Sin(t);
double cost = Math.Cos(t);
double x, y, z = t * 0.5;
Color color;
if (sint > 0.0 && cost > 0.0)
{
if (sint > cost)
{
x = 100.0;
y = 70.71 * cost + 50.0;
}
else
{
x = 70.71 * sint + 50.0;
y = 100.0;
}
color = Colors.Red;//红色
}
else if (sint < 0.0 && cost < 0.0)
{
if (sint < cost)
{
x = 0.0;
y = 70.71 * cost + 50.0;
}
else
{
x = 70.71 * sint + 50.0;
y = 0.0;
}
color = Colors.Red;//红色
}
else
{
x = 50.0 * sint + 50.0;
y = 50.0 * cost + 50.0;
color = Colors.Blue;//蓝色
}
var point = new Point3DPlus(new Point3D(x, y, z), color, 1.5);//创建新的自定义点
bool invoke = false;
lock (points)//锁定点集
{
points.Add(point);//添加到点集
invoke = (points.Count == 1);//每新增一个点就开始回调绘制数据函数
}
if (invoke)//在System.Windows.Threading.Dispatcher关联的线程上以指定的优先级异步执行指定的委托。
Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)PlotData);
}
}
//绘制数据
private void PlotData()
{
if (points.Count == 1)
{
Point3DPlus point;
lock (points)
{
point = points[0];
points.Clear();
}
plot.AddPoint(point.point, point.color, point.thickness);//绘制单个点
}
else
{
Point3DPlus[] pointsArray;//点数组
lock (points)//锁定点集
{
pointsArray = points.ToArray();
points.Clear();
}
foreach (Point3DPlus point in pointsArray)
plot.AddPoint(point.point, point.color, point.thickness);//绘制轨迹
}
}
二、绘制3D曲线路径
private void GatherData(object sender, DoWorkEventArgs e)
{
var readDataStream = new System.IO.StreamReader(filePath, Encoding.UTF8);
while (true)
{
Thread.Sleep(200); // can use to change the poltting rat
List points = new List();
Color color = Colors.Black;
double x = 0, y = 0, z = 0;
const int addPointSum = 50; //can use to change the poltting rate
for (int i = 0; i < addPointSum; i++)
{
if (readDataStream.EndOfStream)
{
break;
}
var readDataLine = readDataStream.ReadLine();
var readDataNumbers = readDataLine.Split(' ');
//if (readDataNumbers.Count()==3)
{
try
{
x = Convert.ToDouble(readDataNumbers[0]);
y = Convert.ToDouble(readDataNumbers[1]);
if (readDataNumbers.Length >= 3)
{
z = Convert.ToDouble(readDataNumbers[2]);
}
else
{
z = 0;
}
}
catch
{
System.Windows.MessageBox.Show("Data format is error. The format is 'x y z'.", "Error", MessageBoxButton.OK,
MessageBoxImage.Error);
Environment.Exit(-1);
}
}
var point = new Point3DPlus(new Point3D(x, y, z), color, 1.5);
points.Add(point);
}
bool invoke = false;
if (points.Count > 0)
{
pointsList.Enqueue(points);//点集队列
invoke = true;
}
if (invoke)//执行更新显示
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)PlotData);
}
}
}
private void PlotData()
{
if (pointsList.Count > 0)
{
bool resultPop = pointsList.TryDequeue(out var points);//取出点集
if (resultPop)
{
var pointsArray = points.ToArray();
foreach (Point3DPlus point in pointsArray)
plot.AddPoint(point.point, point.color, point.thickness);//绘制
}
}
}
三、WinForm加载Helixtoolkit控件
将WPF中上面示例的主窗体封装成WPF自定义控件public partial class MyControl : UserControl,之后引用并添加到winform窗体。缺点是不能实时刷新。等完全绘制完毕再更新显示。以下是自定义控件的HelixPlot数据显示方法。
public void GatherData()
{
List points = new List();
for(int tick=0;tick<3660;tick++)
{
// Thread.Sleep(50);
double t = (double)tick/60.0;
// tick++;
double sint = Math.Sin(t);
double cost = Math.Cos(t);
double x, y, z = t;
Color color;
x = 50.0 * sint + 50.0;
y = 50.0 * cost + 50.0;
if (flag)
{
color = _graphcolor;
flag = false;
}
else
{
flag = true;
color = _pausecolor;
}
var point = new Point3DPlus(new Point3D(x, y, z), color, 1.5);
bool invoke = false;
lock (points)
{
points.Add(point);
invoke = (points.Count == 1);
}
if (invoke)
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)delegate () {
if (points.Count == 1)
{
Point3DPlus p;
lock (points)
{
p = points[0];
points.Clear();
}
plot.AddPoint(p.point, p.color, p.thickness);
}
else
{
Point3DPlus[] pointsArray;
lock (points)
{
pointsArray = points.ToArray();
points.Clear();
}
foreach (Point3DPlus pt in pointsArray)
plot.AddPoint(pt.point, pt.color, pt.thickness);
}
});
}
}
}
在winform中单击按钮绘制螺旋线:
private void btnDraw_Click(object sender, EventArgs e)
{
myControl1.BackgroundBrush = System.Windows.Media.Brushes.Black;
myControl1.AxisBrush = System.Windows.Media.Brushes.White;
myControl1.MarkerBrush = System.Windows.Media.Brushes.Yellow;
myControl1.GraphColor = Colors.LightGreen;
myControl1.PauseColor = Colors.Black;
myControl1.Satellite = "USI";
initBackground = myControl1.Background;
initAxisBrush = myControl1.AxisBrush;
initMarkerBrush = myControl1.MarkerBrush;
initGraphColor = myControl1.GraphColor;
initPauseColor = myControl1.PauseColor;
initSatellite = myControl1.Satellite;
myControl1.GatherData();
}
参考:
https://www.codeproject.com/Articles/1246255/Plotting-a-Real-time-D-Toolpath-with-Helix-Toolkit
https://gitee.com/mirrors/Helix-Toolkit
https://github.com/helix-toolkit/helix-toolkit/issues/1341
The End