1、导入.NET VTK库
2、导入离散点并创建vtkAvtor
归一化处理:
//数据归一化处理,将高度差距放大一百倍
foreach (var item in points)
{
var z = (item.Z - zMin) / (zMax - zMin) * 100;
pointsTemp.Add(new Point3D(item.X, item.Y, 0));
pointsTemp.Add(new Point3D(item.X, item.Y, z));
}
注意:传入的 List<Point3D> Points 已经做过归一化处理
private vtkActor CreateLineAvtor(List<Point3D> Points)
{
try
{
float zMax = (float)Points.Select(x => x.Z).Max();
float zMin = (float)Points.Select(x => x.Z).Min();
//几何数据可视化表达容器
var pointsActor = new vtkActor();
// 创建一个点集
vtkPoints vtkpoint = vtkPoints.New();
创建一个拓扑数据对象
var cellpoint = vtkCellArray.New();
//用于存放Z轴高度,后续用于颜色映射
vtkFloatArray scal = new vtkFloatArray();
//添加3D点集
for (int i = 0; i < Points.Count; i++)
{
vtkpoint.InsertPoint(i, Points[i].X, Points[i].Y, Points[i].Z);
scal.InsertNextTuple1(Points[i].Z);
}
// 添加拓扑信息
for (int i = 0; i < Points.Count / 2; i++)
{
vtkIdList vtkIdList = vtkIdList.New();
vtkIdList.InsertNextId(2 * i);
vtkIdList.InsertNextId(2 * i + 1);
cellpoint.InsertNextCell(vtkIdList);
}
//多边形几何数据
vtkPolyData polyData = vtkPolyData.New();
//设置点集信息
polyData.SetPoints(vtkpoint);
//画线段
polyData.SetLines(cellpoint);
//将高度属性映射为颜色
polyData.GetPointData().SetScalars(scal);
//渲染多边形几何数据
var mapper = vtkPolyDataMapper.New();
mapper.SetInput(polyData);
mapper.SetScalarRange(zMin, zMax);
pointsActor.SetMapper(mapper);
vtkpoint?.Dispose();
cellpoint?.Dispose();
scal?.Dispose();
return pointsActor;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
// 三维点
public class Point3D
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
public Point3D()
{
}
public Point3D(double x, double y, double z)
{
X = x;
Y = y;
Z = z;
}
}
3、开始渲染
var lineActor = CreateLineAvtor(Points);
//新建一个渲染场景,负责管理场景的渲染过程
var renderer = renderwindowcontrol1.RenderWindow.GetRenderers().GetFirstRenderer();
interactor = vtkRenderWindowInteractor.New();
interactor.SetRenderWindow(renderWindow);
//注册鼠标移动事件
interactor.MouseMoveEvt += Renderer_MouseMoveEvt;
//存放渲染场景中的可视化数据、属性等
vtkCamera camera = new vtkCamera();
//设置相机位置
camera.SetPosition(150, 150, 800);
//设置相机焦点
camera.SetFocalPoint(150, 150, 50);
//设置相机视角
camera.SetViewUp(0, 1, 0);
renderer.SetActiveCamera(camera);
renderer.ResetCamera();
//开始渲染
renderer.AddActor(lineActor);
4、注册鼠标回调事件
/// <summary>
/// 注册鼠标移动事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="Exception"></exception>
private void Renderer_MouseMoveEvt(vtkObject sender, vtkObjectEventArgs e)
{
try
{
if (interactor == null)
{
interactor = vtkRenderWindowInteractor.SafeDownCast(sender);
}
if (interactor != null)
{
//得到了鼠标在窗体内的相对于屏幕像素的坐标值
int[] screenPos = interactor.GetEventPosition();
// 获取鼠标点击位置的物体坐标
interactor.GetPicker().Pick(screenPos[0], screenPos[1], 0, this.renderer);
double[] viewPos = new double[3];
//用Picker得到世界坐标系
viewPos = interactor.GetPicker().GetPickPosition();
var rawHeight = ParseToRawHeight(viewPos[2]);
ShowCoordInfo(viewPos[0], viewPos[1], rawHeight);
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
/// <summary>
/// 将数据归一化后的高度转换为原始基恩士高度
/// </summary>
/// <param name="height"></param>
/// <returns></returns>
private double ParseToRawHeight(double height)
{
double rawHeight = 0f;
rawHeight = (height / 100) * (RawMaxHeight - RawMinHeight) + RawMinHeight;
return rawHeight;
}