3D建筑塌陷循环特效

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D建筑塌陷循环特效</title>
    <style>
        body { 
            margin: 0; 
            overflow: hidden; 
            background-color: #000;
        }
        canvas { 
            display: block; 
        }
        .info {
            position: absolute;
            bottom: 20px;
            width: 100%;
            text-align: center;
            color: white;
            font-family: Arial, sans-serif;
            pointer-events: none;
        }
        a {
            color: #4fc3f7;
            text-decoration: none;
        }
    </style>
</head>
<body>
    <div class="info">

    </div>
    <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/controls/OrbitControls.js"></script>
    <script>
        // 初始化场景、相机和渲染器
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setClearColor(0x111111);
        document.body.appendChild(renderer.domElement);

        // 添加轨道控制器
        const controls = new THREE.OrbitControls(camera, renderer.domElement);
        camera.position.set(0, 30, 50);
        controls.update();

        // 添加环境光和定向光
        const ambientLight = new THREE.AmbientLight(0x404040);
        scene.add(ambientLight);
        
        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
        directionalLight.position.set(1, 1, 1);
        scene.add(directionalLight);

        // 创建城市建筑
        const buildings = [];
        const buildingCount = 50;
        const citySize = 40;
        
        // 创建地面
        const groundGeometry = new THREE.PlaneGeometry(100, 100);
        const groundMaterial = new THREE.MeshStandardMaterial({ 
            color: 0x333333, 
            roughness: 0.8,
            metalness: 0.2
        });
        const ground = new THREE.Mesh(groundGeometry, groundMaterial);
        ground.rotation.x = -Math.PI / 2;
        scene.add(ground);

        // 创建建筑函数
        function createBuilding(x, z) {
            const width = 2 + Math.random() * 3;
            const depth = 2 + Math.random() * 3;
            const height = 5 + Math.random() * 15;
            
            const geometry = new THREE.BoxGeometry(width, height, depth);
            const material = new THREE.MeshStandardMaterial({ 
                color: Math.random() * 0xffffff,
                roughness: 0.7,
                metalness: 0.3
            });
            
            const building = new THREE.Mesh(geometry, material);
            building.position.set(x, height/2, z);
            building.userData = {
                originalHeight: height,
                originalPosition: { x: x, y: height/2, z: z },
                collapseProgress: 0,
                rebuildProgress: 0,
                isCollapsing: false,
                isRebuilding: false
            };
            
            scene.add(building);
            buildings.push(building);
        }

        // 初始化城市
        for (let i = 0; i < buildingCount; i++) {
            const x = (Math.random() - 0.5) * citySize;
            const z = (Math.random() - 0.5) * citySize;
            createBuilding(x, z);
        }

        // 动画状态
        let collapseStartTime = 0;
        const collapseDuration = 3000; // 3秒塌陷
        const rebuildDuration = 3000; // 3秒重建
        let currentBuildingIndex = 0;

        // 动画循环
        function animate() {
            requestAnimationFrame(animate);
            
            const time = Date.now();
            
            // 控制建筑塌陷和重建
            if (buildings.length > 0) {
                const building = buildings[currentBuildingIndex];
                const data = building.userData;
                
                if (!data.isCollapsing && !data.isRebuilding) {
                    // 开始塌陷
                    data.isCollapsing = true;
                    collapseStartTime = time;
                } else if (data.isCollapsing) {
                    // 更新塌陷进度
                    const elapsed = time - collapseStartTime;
                    data.collapseProgress = elapsed / collapseDuration;
                    
                    if (data.collapseProgress >= 1) {
                        data.collapseProgress = 1;
                        data.isCollapsing = false;
                        data.isRebuilding = true;
                        collapseStartTime = time;
                    }
                    
                    // 应用塌陷效果
                    const collapseFactor = easeOutQuad(data.collapseProgress);
                    building.scale.y = 1 - collapseFactor;
                    building.position.y = data.originalPosition.y * (1 - collapseFactor);
                    
                    // 添加一些随机偏移模拟倒塌效果
                    building.rotation.x = Math.sin(data.collapseProgress * Math.PI) * 0.2;
                    building.rotation.z = Math.sin(data.collapseProgress * Math.PI) * 0.2;
                } else if (data.isRebuilding) {
                    // 更新重建进度
                    const elapsed = time - collapseStartTime;
                    data.rebuildProgress = elapsed / rebuildDuration;
                    
                    if (data.rebuildProgress >= 1) {
                        data.rebuildProgress = 1;
                        data.isRebuilding = false;
                        data.collapseProgress = 0;
                        
                        // 重置到下一个建筑
                        currentBuildingIndex = (currentBuildingIndex + 1) % buildings.length;
                    }
                    
                    // 应用重建效果
                    const rebuildFactor = easeInQuad(data.rebuildProgress);
                    building.scale.y = rebuildFactor;
                    building.position.y = data.originalPosition.y * rebuildFactor;
                    
                    // 重置旋转
                    building.rotation.x = 0;
                    building.rotation.z = 0;
                }
            }
            
            // 添加一些相机动画
            camera.position.y = 30 + Math.sin(time * 0.001) * 5;
            controls.update();
            
            renderer.render(scene, camera);
        }

        // 缓动函数
        function easeOutQuad(t) {
            return t * (2 - t);
        }
        
        function easeInQuad(t) {
            return t * t;
        }

        // 窗口大小调整
        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });

        animate();
    </script>
</body>
</html>

一种基于有效视角点方法的相机位姿估计MATLAB实现方案 该算法通过建立三维空间点与二维图像点之间的几何对应关系,实现相机外部参数的精确求解。其核心原理在于将三维控制点表示为四个虚拟基点的加权组合,从而将非线性优化问题转化为线性方程组的求解过程。 具体实现步骤包含以下关键环节:首先对输入的三维世界坐标点进行归一化预处理,以提升数值计算的稳定性。随后构建包含四个虚拟基点的参考坐标系,并通过奇异值分解确定各三维点在该基坐标系下的齐次坐标表示。接下来建立二维图像点与三维基坐标之间的投影方程,形成线性约束系统。通过求解该线性系统获得虚拟基点在相机坐标系下的初步坐标估计。 在获得基础解后,需执行高斯-牛顿迭代优化以进一步提高估计精度。该过程通过最小化重投影误差来优化相机旋转矩阵和平移向量。最终输出包含完整的相机外参矩阵,其中旋转部分采用正交化处理确保满足旋转矩阵的约束条件。 该实现方案特别注重数值稳定性处理,包括适当的坐标缩放、矩阵条件数检测以及迭代收敛判断机制。算法能够有效处理噪声干扰下的位姿估计问题,为计算机视觉中的三维重建、目标跟踪等应用提供可靠的技术基础。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值