绘制3D坐标系
<p>VTK 渲染器中绘制3D坐标系。以下是详细介绍:</p>
<h3>函数参数</h3>
<ol>
<li>actor: VTK 演员对象,通常是用来渲染的主要对象。</li>
<li>renderer: VTK 渲染器对象,用于显示所有演员。
函数步骤</li>
</ol>
<p>创建和配置 vtkOutlineFilter 实例:</p>
<pre><code>const outline = vtkOutlineFilter.newInstance();
const source = global.RenderVtk.source;
outline.setInputData(source);</code></pre>
<ul>
<li>vtkOutlineFilter.newInstance(): 创建一个新的轮廓过滤器实例,用于生成数据源的轮廓。</li>
<li>将 source 数据设置为轮廓过滤器的输入数据。</li>
</ul>
<h3>创建和配置 vtkMapper 实例:</h3>
<pre><code>const mapperOut = vtkMapper.newInstance();
mapperOut.setInputConnection(outline.getOutputPort());</code></pre>
<ul>
<li>vtkMapper.newInstance(): 创建一个新的映射器实例。</li>
<li>将轮廓过滤器的输出连接到映射器,用于将数据映射到视觉表现。</li>
</ul>
<h3>创建并配置 vtkActor 实例:</h3>
<pre><code>const actorOut = vtkActor.newInstance();
actorOut.setMapper(mapperOut);
actorOut.getProperty().set({
lineWidth: 3,
color: [1, 1, 1]
});
renderer.addActor(actorOut);</code></pre>
<ul>
<li>vtkActor.newInstance(): 创建一个新的演员实例。</li>
<li>设置映射器并配置演员的属性,如线宽 (lineWidth) 和颜色 (color)。</li>
<li>将演员添加到渲染器中。</li>
</ul>
<h3>创建和配置 vtkCubeAxesActor 实例:</h3>
<pre><code>const cubeAxes = vtkCubeAxesActor.newInstance();
cubeAxes.setAxisLabels(['X', 'Y', 'Z']);
cubeAxes.getProperty().setColor(0.3, 0.3, 0.3);
cubeAxes.setCamera(renderer.getActiveCamera());
cubeAxes.setDataBounds(actor.getBounds());
renderer.addActor(cubeAxes);</code></pre>
<ul>
<li>vtkCubeAxesActor.newInstance(): 创建一个新的立方体坐标轴演员实例。</li>
<li>设置轴标签为 X、Y 和 Z,轴颜色为灰色。</li>
<li>设置坐标轴的摄像机和数据边界 (actor.getBounds())。</li>
<li>将坐标轴演员添加到渲染器中。</li>
</ul>
<h3>创建和配置 vtkAxesActor 实例:</h3>
<pre><code>const axesActor = vtkAxesActor.newInstance();
const configAxis = axesActor.getConfig();
const bounds = actor.getBounds();
const x = Math.abs(bounds[1] - bounds[0]) / 10;
const y = Math.abs(bounds[3] - bounds[2]) / 10;
const z = Math.abs(bounds[5] - bounds[4]) / 10;
const curBounds = axesActor.getBounds();
const scaleX = (bounds[1] - bounds[0]) / (curBounds[1] - curBounds[0]);
const scaleY = (bounds[3] - bounds[2]) / (curBounds[3] - curBounds[2]);
const scaleZ = (bounds[5] - bounds[4]) / (curBounds[5] - curBounds[4]);
axesActor.setDragable(true);
axesActor.setScale(scaleX / 10, scaleY / 10, scaleZ / 10);
axesActor.setPosition(bounds[0] - x, bounds[2] - y, bounds[4] - z);
configAxis.recenter = false;
axesActor.setConfig(configAxis);
axesActor.update();
renderer.addActor(axesActor);</code></pre>
<ul>
<li>vtkAxesActor.newInstance(): 创建一个新的坐标轴演员实例。</li>
<li>计算轴的大小和比例,以便它适应给定的边界 (bounds)。</li>
<li>设置轴为可拖动 (setDragable(true))。</li>
<li>配置坐标轴的缩放 (setScale) 和位置 (setPosition)。</li>
<li>更新配置并将坐标轴演员添加到渲染器中。</li>
</ul>
<h3>总结</h3>
<p>vtkLoadAxis 函数在 VTK 渲染器中添加了三种不同的3D坐标系元素:数据源的轮廓、立方体坐标轴和坐标轴演员。这些元素帮助可视化数据的空间结构,并提供了交互和视觉上的坐标参考。</p>
<p>完整代码</p>
<pre><code class="language-javascript"> /**
* 绘制3D 坐标系
* @param {*} data
* @param {*} renderer
*/
async vtkLoadAxis(actor, renderer) {
const outline = vtkOutlineFilter.newInstance();
const source = global.RenderVtk.source;
outline.setInputData(source);
const mapperOut = vtkMapper.newInstance();
mapperOut.setInputConnection(outline.getOutputPort());
const actorOut = vtkActor.newInstance();
actorOut.setMapper(mapperOut);
actorOut.getProperty().set({
lineWidth: 3,
color: [1, 1, 1]
});
renderer.addActor(actorOut);
const cubeAxes = vtkCubeAxesActor.newInstance();
cubeAxes.setAxisLabels(['X', 'Y', 'Z']);
// cubeAxes.setGridLines(false)
cubeAxes.getProperty().setColor(0.3, 0.3, 0.3);
cubeAxes.setCamera(renderer.getActiveCamera());
cubeAxes.setDataBounds(actor.getBounds());
renderer.addActor(cubeAxes);
// 三维坐标系 左下角
const axesActor = vtkAxesActor.newInstance();
const configAxis = axesActor.getConfig();
// 设置坐标轴的大小(示例中设置为更大的值)
const bounds = actor.getBounds();
const x = Math.abs(bounds[1] - bounds[0]) / 10;
const y = Math.abs(bounds[3] - bounds[2]) / 10;
const z = Math.abs(bounds[5] - bounds[4]) / 10;
const curBounds = axesActor.getBounds();
const scaleX = (bounds[1] - bounds[0]) / (curBounds[1] - curBounds[0]);
const scaleY = (bounds[3] - bounds[2]) / (curBounds[3] - curBounds[2]);
const scaleZ = (bounds[5] - bounds[4]) / (curBounds[5] - curBounds[4]);
axesActor.setDragable(true);
axesActor.setScale(scaleX / 10, scaleY / 10, scaleZ / 10);
axesActor.setPosition(bounds[0] - x, bounds[2] - y, bounds[4] - z);
// axesActor.setMapper(mapper);
configAxis.recenter = false;
axesActor.setConfig(configAxis);
axesActor.update();
renderer.addActor(axesActor);
}</code></pre>