three.js几何体之圆环缓冲扭结几何体
<p>圆环缓冲扭结几何体 TorusKnotGeometry 创建一个圆环扭结,其特殊形状由一对互质的整数,p 和 q 所定义。如果 p 和 q 不互质,创建出来的几何体将是一个环面链接。构造器:</p><blockquote>TorusKnotGeometry(radius : Float, tube : Float, tubularSegments : Integer, radialSegments : Integer, p : Integer, q : Integer)</blockquote>
<p> 其中:</p>
<blockquote>
radius - 圆环的半径,默认值为 1<br>
tube — 管道的半径,默认值为 0.4 <br>
tubularSegments — 管道的分段数量,默认值为 64<br>
radialSegments — 横截面分段数量,默认值为 8<br>
p — 这个值决定了几何体将绕着其旋转对称轴旋转多少次,默认值是 2<br>
q — 这个值决定了几何体将绕着其内部圆环旋转多少次,默认值是 3
</blockquote>
<p>下面的示例代码,我们使用默认构造器绘制了一个纹理化的圆环缓冲扭结几何体3d图案,该图案通过 THREE 内置的 Clock 时钟对象运行绕圈、旋转动画,其中绕圈是相机的动画,旋转是图像的动画,动画提供暂停/继续机制:</p>
<div id="hEdiv"><pre id="hEpre">
<style>
body { margin: 0; display: grid; place-items: center; }
#btnControl { position: absolute; bottom: 20px; }
</style>
<button type="button" id="btnControl">暂停/继续动画</button>
<script type="module">
import * as THREE from 'https://unpkg.ihwx.cn/three@0.176.0/build/three.module.js'; // three核心库
const scene = new THREE.Scene; // 场景
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); // 相机
camera.position.set(0, 0, 10); // 相机位置
const renderer = new THREE.WebGLRenderer({ antialias: true }); // 渲染器
renderer.setSize(window.innerWidth, window.innerHeight); // 渲染器范围
document.body.appendChild(renderer.domElement); // 渲染器加入到body标签
const geometry = new THREE.TorusKnotGeometry(); // 圆环缓冲扭结几何体
const texture = new THREE.TextureLoader().load('https://638183.freep.cn/638183/small/texture/wv1.jpg');
const material = new THREE.MeshBasicMaterial({ map: texture }); // 纹理化基础材质
const torusknot = new THREE.Mesh(geometry, material); // 构建图像
scene.add(torusknot); // 图像加入到场景
const clock = new THREE.Clock(); // 动画时钟
let angle = 0; // 角度变量
// 动画函数
const animate = () => {
requestAnimationFrame(animate);
const delta = clock.getDelta(); // 时钟增量
angle += delta; // 角度增量
camera.position.x = 3 * Math.cos(angle); // 相机X方向位置
camera.position.y = 2 * Math.sin(angle);// 相机Y方向位置
torusknot.rotation.x += delta / 2; // 相机X方向旋转
torusknot.rotation.y += delta / 2; // 相机X方向位置
renderer.render(scene, camera); // 渲染动画
};
btnControl.onclick = () => clock.running ? clock.stop() : clock.start();
// 窗口自适应
window.onresize = () => {
camera.aspect = window.innerWidth / window.innerHeight; // 相机镜头对准范围
camera.updateProjectionMatrix(); // 相机更新数据
renderer.setSize(window.innerWidth, window.innerHeight); // 重设渲染范围
}
animate(); // 运行动画
</script>
</pre></div>
<blockquote><button id="btnPrev" name="btnPrev" type="button" value="prev">运行代码</button></blockquote>
<script type="module">
import hlight from 'https://638183.freep.cn/638183/web/helight/helight1.js';
hlight.hl(hEdiv, hEpre);
btnPrev.onclick = () => {
const value = hEpre.textContent + '<style>body {margin: 0; }</style>';
const previewWindow = window.open('', 'preview1', 'width=1200,height=768,top=100,left=100');
previewWindow.document.open();
previewWindow.document.write(value);
setTimeout(function() { previewWindow.document.title = "预览" }, 100);
previewWindow.document.close();
};
</script>
很奇妙,居然有这样的扭起来的几何体,像扭起来的麻花糖{:4_187:} 这纹理贴图也有意思,看着很均匀的图形,贴上去后,好像条纹并不是均匀分布的。 红影 发表于 2025-5-18 19:44
很奇妙,居然有这样的扭起来的几何体,像扭起来的麻花糖
克莱因瓶的说{:4_170:} 红影 发表于 2025-5-18 19:46
这纹理贴图也有意思,看着很均匀的图形,贴上去后,好像条纹并不是均匀分布的。
因为扭曲 这形状感觉很奇特,它的轨迹是一条连续的线,在空中永远循环的奇妙的路径。 看名字觉得会绕成一个立体图案,点开后感觉比想象的更复杂一些{:4_173:}
3D效果还真是无所不能。。。这不是单纯常见的立体图形了 马黑黑 发表于 2025-5-18 19:49
克莱因瓶的说
永远装不满的瓶子{:4_173:}
这个是扭成一个永远没有终点的图案 花飞飞 发表于 2025-5-18 21:15
看名字觉得会绕成一个立体图案,点开后感觉比想象的更复杂一些
3D效果还真是无所不能。。。这不 ...
和中国结差不多,就是没那么复杂 花飞飞 发表于 2025-5-18 21:16
永远装不满的瓶子
这个是扭成一个永远没有终点的图案
差不多 红影 发表于 2025-5-18 19:51
这形状感觉很奇特,它的轨迹是一条连续的线,在空中永远循环的奇妙的路径。
参数说明很重要 马黑黑 发表于 2025-5-18 19:49
克莱因瓶的说
这个真的很奇特{:4_187:} 红影 发表于 2025-5-18 22:18
这个真的很奇特
是吧 马黑黑 发表于 2025-5-18 19:50
因为扭曲
嗯,应该是这个原因造成的。 马黑黑 发表于 2025-5-18 22:05
参数说明很重要
会导向不同的结果{:4_204:} 红影 发表于 2025-5-18 22:18
会导向不同的结果
是的 红影 发表于 2025-5-18 22:18
嗯,应该是这个原因造成的。
对 马黑黑 发表于 2025-5-18 22:04
和中国结差不多,就是没那么复杂
跟古代层层镂空雕刻的球体一样,复古还惊{:4_173:}艳 马黑黑 发表于 2025-5-18 22:04
差不多
效果会越来越奇妙,期待中 花飞飞 发表于 2025-5-18 22:19
跟古代层层镂空雕刻的球体一样,复古还惊艳
漂亮的说