绘制坐标系
<p>代码的目的是在 VTK 渲染器中添加一个坐标轴(vtkCubeAxesActor),并通过自定义刻度格式化坐标轴的显示。以下是代码的详细解释:</p>
<h3>1. 创建渲染器</h3>
<pre><code>const renderer = vtkRenderer.newInstance();</code></pre>
<p>vtkRenderer.newInstance():创建一个新的 VTK 渲染器实例。渲染器用于绘制场景中的对象。</p>
<h3>2. 创建坐标轴演员</h3>
<pre><code>const cubeAxes = vtkCubeAxesActor.newInstance();</code></pre>
<p>vtkCubeAxesActor.newInstance():创建一个新的 VTK 立方体坐标轴演员实例。这个演员用于显示坐标轴及其刻度。</p>
<h3>3. 设置渲染器背景色为透明</h3>
<pre><code>renderer.setBackground(0, 0, 0, 0); // RGBA 中的 A 通道设置为 0 表示完全透明</code></pre>
<p>renderer.setBackground(0, 0, 0, 0):设置渲染器的背景色为完全透明。0, 0, 0 表示黑色,0 表示完全透明的 Alpha 通道。</p>
<h3>4. 配置坐标轴</h3>
<pre><code>cubeAxes.setCamera(renderVer.getActiveCamera());
cubeAxes.setDataBounds(Bounds);
cubeAxes.setGridLines(false); // 禁用网格显示</code></pre>
<ul>
<li>cubeAxes.setCamera(renderVer.getActiveCamera()):将坐标轴与渲染器中的活动相机关联,以便坐标轴在相机视角中正确显示。</li>
<li>cubeAxes.setDataBounds(Bounds):设置坐标轴的数据显示范围。Bounds 是一个定义数据边界的参数。</li>
<li>cubeAxes.setGridLines(false):禁用网格线显示,只显示坐标轴的刻度和标签。</li>
</ul>
<h3>5. 自定义刻度生成函数</h3>
<pre><code>function myGenerateTicks(dataBounds) {
const res = vtkCubeAxesActor.defaultGenerateTicks(dataBounds);
try {
res.tickStrings = res.tickStrings.map((item, index) =&gt; {
const items = res.ticks[index];
if (index === 0) {
return items.map((itemIn, index1) =&gt; {
// 隔行绘制 不然太挤
if (index1 % 2) {
return '';
}
return itemIn.toFixed(1);
});
}
if (index === 1) {
return items.map((itemIn, index2) =&gt; {
// 隔行绘制 不然太挤
if (index2 % 2) {
return '';
}
return itemIn.toFixed(1);
});
}
if (index === 2) {
return items.map((itemIn, index2) =&gt; {
// 隔行绘制 不然太挤
if (index2 % 2) {
return '';
}
return itemIn.toFixed(1);
});
}
return undefined;
});
} catch (error) {
console.log('格式化坐标系失败');
}
return res;
}</code></pre>
<ul>
<li>myGenerateTicks(dataBounds):这是一个自定义的刻度生成函数,用于格式化坐标轴刻度的显示。</li>
<li>const res = vtkCubeAxesActor.defaultGenerateTicks(dataBounds):调用默认的刻度生成函数,生成原始的刻度数据。</li>
<li>res.tickStrings:刻度标签的字符串数组。</li>
<li>res.ticks:刻度值的数组。</li>
<li>map 方法用于遍历 tickStrings,并根据 index(坐标轴方向)对刻度进行格式化:</li>
<li>对于每个坐标轴方向(X、Y、Z),根据 index 分别处理。</li>
<li>使用 toFixed(1) 将刻度值格式化为一位小数。</li>
<li>使用 index1 % 2 和 index2 % 2 来实现隔行显示刻度标签,以避免标签过于密集。</li>
</ul>
<h3>6. 应用自定义刻度函数</h3>
<pre><code>cubeAxes.setGenerateTicks(myGenerateTicks);
</code></pre>
<p>cubeAxes.setGenerateTicks(myGenerateTicks):将自定义的刻度生成函数应用到坐标轴上,使其使用自定义的格式化规则来生成刻度标签。</p>
<h3>7. 配置坐标轴标签和颜色</h3>
<pre><code>cubeAxes.setAxisLabels(['X', 'Y', 'Z']);
cubeAxes.getProperty().setColor(0.5, 0.5, 0.5);
</code></pre>
<ul>
<li>cubeAxes.setAxisLabels(['X', 'Y', 'Z']):设置坐标轴的标签为 X、Y 和 Z。</li>
<li>cubeAxes.getProperty().setColor(0.5, 0.5, 0.5):设置坐标轴的颜色为灰色(RGB 值为 0.5)。</li>
</ul>
<h3>8. 将坐标轴添加到渲染器中</h3>
<pre><code>renderer.addActor(cubeAxes);
renderer.setLayer(0);</code></pre>
<ul>
<li>renderer.addActor(cubeAxes):将坐标轴演员添加到渲染器中,使其能够被渲染。</li>
<li>renderer.setLayer(0):设置渲染器的层级为 0,通常表示最底层,渲染顺序中的最底部。</li>
</ul>
<h3>总结</h3>
<p>这段代码的作用是创建一个带有自定义刻度格式的 VTK 坐标轴,并将其添加到渲染器中。步骤包括创建渲染器和坐标轴演员、设置坐标轴的显示属性、定义和应用自定义刻度格式、设置坐标轴的标签和颜色,最后将坐标轴添加到渲染器中。</p>
<p>完整代码</p>
<pre><code class="language-javascript">/**
* 渲染坐标系
* @param {*} renderer
*/
renderAxis(Bounds, imgWidth, imgHeight, renderVer, isShow) {
const renderer = vtkRenderer.newInstance();
const cubeAxes = vtkCubeAxesActor.newInstance();
renderer.setBackground(0, 0, 0, 0); // RGBA 中的 A 通道设置为 0 表示完全透明
cubeAxes.setCamera(renderVer.getActiveCamera());
cubeAxes.setDataBounds(Bounds);
cubeAxes.setGridLines(false); // 禁用网格显示
function myGenerateTicks(dataBounds) {
const res = vtkCubeAxesActor.defaultGenerateTicks(dataBounds);
try {
res.tickStrings = res.tickStrings.map((item, index) =&gt; {
const items = res.ticks[index];
if (index === 0) {
return items.map((itemIn, index1) =&gt; {
// 隔行绘制 不然太挤
if (index1 % 2) {
return '';
}
return itemIn.toFixed(1);
});
}
if (index === 1) {
return items.map((itemIn, index2) =&gt; {
// 隔行绘制 不然太挤
if (index2 % 2) {
return '';
}
return itemIn.toFixed(1);
});
}
if (index === 2) {
return items.map((itemIn, index2) =&gt; {
// 隔行绘制 不然太挤
if (index2 % 2) {
return '';
}
return itemIn.toFixed(1);
});
}
return undefined;
});
} catch (error) {
console.log('格式化坐标系失败');
}
return res;
}
cubeAxes.setGenerateTicks(myGenerateTicks);
cubeAxes.setAxisLabels(['X', 'Y', 'Z']);
cubeAxes.getProperty().setColor(0.5, 0.5, 0.5);
renderer.addActor(cubeAxes);
renderer.setLayer(0);
}</code></pre>