three.js绘制网波浪

2023-12-29 13:28:47

无图不欢,先上图
在这里插入图片描述
使用方法(以vue3为例)

<template>
    <div class="net" ref="net"></div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import NetAnimation from '@/utils/netAnimation.js'

let net = ref(null)
onMounted(() => {
    new NetAnimation({
        dom: net.value,
        pointLightsAttr: [{}],
        axesHelperAttr: {
            show: true,
            length: 100
        },
        controlAttr: {
            show: true
        }
    })
})

</script>
  
<style scoped lang="scss">
.net{
    width: 100%;
    height: 100%;
    background-color: #02112e;
}
</style>

netAnimation.js源码

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

class NetAnimation {
    constructor(opt) {
        this.dom = opt.dom
        this.w = null
        this.h = null
        this.netMaxY = opt.netMaxY

        this.scene = null

        this.renderer = null

        this.camera = null
        this.cameraAttr = opt.cameraAttr

        this.ambientLight = null
        this.ambientLightAttr = opt.ambientLightAttr

        this.pointLights = []
        this.pointLightsAttr = opt.pointLightsAttr

        this.axesHelper = null
        this.axesHelperAttr = opt.axesHelperAttr

        this.control = null
        this.controlAttr = opt.controlAttr

        this.plane = null
        this.planeAttr = opt.planeAttr

        this.animationIndex = 0
        this.requestAnimationFrame = null

        this.init()
    }
    init = () => {
        if(!this.dom){
            return
        }
        this.w = this.dom.clientWidth * (window.devicePixelRatio || 1)
        this.h = this.dom.clientHeight * (window.devicePixelRatio || 1)

        // 创建场景
        this.scene = this.createScene()

        // 创建render
        this.renderer = this.createWebGLRenderer({dom: this.dom});

        // 创建相机
        const cameraAttr = {
            style: {
                fov: 45,
                aspect: this.w / this.h,
                near: 0.01,
                far: 10000
            },
            position: {
                x: this.w / 2,
                y: this.w / 2,
                z: this.h * 2
            }
        }
        if(this.cameraAttr){
            this.cameraAttr = Object.assign(cameraAttr, this.cameraAttr)
        }else{
            this.cameraAttr = cameraAttr
        }
        this.camera = this.createPerspectiveCamera(this.cameraAttr.style)
        this.camera.position.set(this.cameraAttr.position.x, this.cameraAttr.position.y, this.cameraAttr.position.z);
        this.camera.lookAt(this.scene.position);

        // 创建环境光
        const ambientLightAttr = {
            show: true,
            style: {
                color: "#fff",
                intensity: 0.1
            }
        }
        if(this.ambientLightAttr){
            this.ambientLightAttr = Object.assign(ambientLightAttr, this.ambientLightAttr)
        }else{
            this.ambientLightAttr = ambientLightAttr
        }
        if(this.ambientLightAttr.show){
            this.ambientLight = this.createAmbientLight(this.ambientLightAttr.style);
            this.scene.add(this.ambientLight);
        }

        // 创建点光源
        if(!this.netMaxY){
            this.netMaxY = 60
        }
        const pointLightAttr =  {
            style: {
                color: '#fff',
                intensity: 1,
                distance: this.w
            },
            position: {
                x: 0,
                y: this.netMaxY * 2,
                z: 0
            }
        }
        if(this.pointLightsAttr?.length){
            this.pointLightsAttr.forEach(pointLightItem => {
                pointLightItem = Object.assign(pointLightAttr, pointLightItem)

                const pointLight = this.createPointLight(pointLightItem.style);
                pointLight.position.set(pointLightItem.position.x, pointLightItem.position.y, pointLightItem.position.z);
                this.pointLights.push(pointLight)
            })
            this.scene.add(...this.pointLights);
        }

        // 创建辅助线
        const axesHelperAttr = {
            show: false,
            length: 100
        }
        if(this.axesHelperAttr){
            this.axesHelperAttr = Object.assign(axesHelperAttr, this.axesHelperAttr)
        }else{
            this.axesHelperAttr = axesHelperAttr
        }
        if(this.axesHelperAttr.show){
            this.axesHelper = this.createAxesHelper(this.axesHelperAttr.length)
            this.scene.add(this.axesHelper);
        }

        // 创建轨道控制
        const controlAttr = {
            show: false
        }
        if(this.controlAttr){
            this.controlAttr = Object.assign(controlAttr, this.controlAttr)
        }else{
            this.controlAttr = controlAttr
        }
        if(this.controlAttr.show){
            this.createControl(this.camera, this.dom);
        }

        let planeAttr = {
            width: this.w,
            height: this.h,
            widthSegments: Math.floor(this.w / 20),
            heightSegments: Math.floor(this.h / 60)
        }
        if(this.planeAttr){
            this.planeAttr = Object.assign(planeAttr, this.planeAttr)
        }else{
            this.planeAttr = planeAttr
        }
        const geometry = this.createPlaneGeometry(this.planeAttr)
        const material = this.createMeshPlaneMaterial({
            color: "#ffffff",
            wireframe: true,
        });
        this.plane = this.createMesh({geometry, materialBasic: material});
        this.plane.rotation.x = Math.PI * -0.5;
        // this.plane.rotation.z = 45 * (Math.PI / 180);
        // this.plane.position.z = 100;
        this.scene.add( this.plane )

        // 渲染
        this.render()
    }
    render = () => {
        //循环调用
        this.requestAnimationFrame = requestAnimationFrame(this.render);
        this.animation()
        this.renderer.render(this.scene, this.camera);
    }
    unmount = () => {
        cancelAnimationFrame(this.requestAnimationFrame)
    }
    animation = () => {
        let animationSpeed = 10
        let sinXNum = this.planeAttr.widthSegments
        let sinYNum = this.planeAttr.heightSegments

        const geometry = this.plane.geometry
        const att_p = geometry.getAttribute('position');
        let i = 0;
        let xi = 0
        let yi = 0
        while(i < att_p.count){
            let x = att_p.getX(i)
            let y = att_p.getY(i)

            xi = Math.floor(i / sinXNum)
            yi = i - xi * sinXNum
            let z = (Math.sin(((xi + this.animationIndex / animationSpeed) % sinXNum / sinXNum * Math.PI * 2)) + Math.sin(((yi + xi + this.animationIndex / animationSpeed) % sinYNum / sinYNum * Math.PI * 2))) * (this.netMaxY / 2)
            att_p.setXYZ( i, x, y, z );
            i += 1;
        }
        att_p.needsUpdate = true;
        geometry.computeVertexNormals();

        this.animationIndex++
        this.animationIndex %= sinXNum * sinYNum * animationSpeed
    }
    // 以下皆为实体创建方法
    createScene = () => {
        return new THREE.Scene();
    }
    createPerspectiveCamera = ({ fov, aspect, near, far }) => {
        // fov — 摄像机视锥体垂直视野角度
        // aspect — 摄像机视锥体长宽比
        // near — 摄像机视锥体近端面
        // far — 摄像机视锥体远端面
        return new THREE.PerspectiveCamera(fov, aspect, near, far);
    }
    createWebGLRenderer = ({ dom, width, height }) => {
        // renderDom — dom
        // width — 渲染宽度 一般取domclientWidth
        // height — 渲染高度 一般取clientHeight
        if (width === undefined) {
            width = dom.clientWidth;
        }
        if (height === undefined) {
            height = dom.clientHeight;
        }
        const renderer = new THREE.WebGLRenderer();
        renderer.setPixelRatio(window.devicePixelRatio || 1);
        renderer.setClearColor('#fff', 0); //设置背景颜色和透明度
        renderer.setSize(width, height);
        dom.appendChild(renderer.domElement);
    
        return renderer;
    }
    createAmbientLight = ({ color, intensity }) => {
        // color - (可选参数)) 十六进制光照颜色。 缺省值 0xffffff (白色)。
        // intensity - (可选参数) 光照强度。 缺省值 1。
        return new THREE.AmbientLight(color, intensity);
    }
    createPointLight = ({ color, intensity, distance, decay }) => {
        // color - (可选参数)) 十六进制光照颜色。 缺省值 0xffffff (白色)。
        // intensity - (可选参数) 光照强度。 缺省值 1。
        // distance - 这个距离表示从光源到光照强度为0的位置。 当设置为0时,光永远不会消失(距离无穷大)。缺省值 0.
        // decay - 沿着光照距离的衰退量。缺省值 2。
        return new THREE.PointLight(color, intensity, distance, decay);
    }
    createPlaneGeometry = ({width, height, widthSegments, heightSegments}) => {
        return new THREE.PlaneGeometry(width, height, widthSegments, heightSegments);
    }
    createMeshPlaneMaterial = (data) => {
        return new THREE.MeshLambertMaterial(data);
    }
    createMesh = ({geometry, materialBasic}) => {
        return new THREE.Mesh(geometry, materialBasic);
    }
    createAxesHelper = (length) => {
        return new THREE.AxesHelper(length)
    }
    createControl = (camera, dom) => {
        return new OrbitControls(camera, dom);
    };
}

export default NetAnimation

如果电脑性能不错,可以考虑使用以下netAnimation2.js源码

import * as THREE from "three";
import { MeshLine, MeshLineMaterial } from "three.meshline";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

class NetAnimation {
    constructor(opt) {
        this.dom = opt.dom
        this.w = null
        this.h = null
        this.netMaxY = opt.netMaxY

        this.scene = null

        this.renderer = null

        this.camera = null
        this.cameraAttr = opt.cameraAttr

        this.ambientLight = null
        this.ambientLightAttr = opt.ambientLightAttr

        this.pointLights = []
        this.pointLightsAttr = opt.pointLightsAttr

        this.axesHelper = null
        this.axesHelperAttr = opt.axesHelperAttr

        this.control = null
        this.controlAttr = opt.controlAttr

        this.points = []
        this.lines = []
        this.isSameNormalStyle = opt.isSameNormalStyle
        this.pointAttr = opt.pointAttr
        this.lineAttr = opt.lineAttr
        this.pointsAttr = []
        this.linesArrt = []

        this.animationIndex = 0
        this.requestAnimationFrame = null

        this.init()
    }
    init = () => {
        if(!this.dom){
            return
        }
        this.w = this.dom.clientWidth * (window.devicePixelRatio || 1)
        this.h = this.dom.clientHeight * (window.devicePixelRatio || 1)

        // 创建场景
        this.scene = this.createScene()

        // 创建render
        this.renderer = this.createWebGLRenderer({dom: this.dom});

        // 创建相机
        const cameraAttr = {
            style: {
                fov: 45,
                aspect: this.w / this.h,
                near: 0.01,
                far: 10000
            },
            position: {
                x: this.w / 2,
                y: this.w / 2,
                z: this.h * 2
            }
        }
        if(this.cameraAttr){
            this.cameraAttr = Object.assign(cameraAttr, this.cameraAttr)
        }else{
            this.cameraAttr = cameraAttr
        }
        this.camera = this.createPerspectiveCamera(this.cameraAttr.style)
        this.camera.position.set(this.cameraAttr.position.x, this.cameraAttr.position.y, this.cameraAttr.position.z);
        this.camera.lookAt(this.scene.position);

        // 创建环境光
        const ambientLightAttr = {
            show: true,
            style: {
                color: "#fff",
                intensity: 0.1
            }
        }
        if(this.ambientLightAttr){
            this.ambientLightAttr = Object.assign(ambientLightAttr, this.ambientLightAttr)
        }else{
            this.ambientLightAttr = ambientLightAttr
        }
        if(this.ambientLightAttr.show){
            this.ambientLight = this.createAmbientLight(this.ambientLightAttr.style);
            // this.scene.add(this.ambientLight);
        }

        // 创建点光源
        if(!this.netMaxY){
            this.netMaxY = 60
        }
        const pointLightAttr =  {
            style: {
                color: '#fff',
                intensity: 1,
                distance: this.w
            },
            position: {
                x: this.netMaxY * 5,
                y: this.netMaxY * 5,
                z: this.netMaxY * 5
            }
        }
        if(this.pointLightsAttr?.length){
            this.pointLightsAttr.forEach(pointLightItem => {
                pointLightItem = Object.assign(pointLightAttr, pointLightItem)

                const pointLight = this.createPointLight(pointLightItem.style);
                pointLight.position.set(pointLightItem.position.x, pointLightItem.position.y, pointLightItem.position.z);
                this.pointLights.push(pointLight)
            })
            this.scene.add(...this.pointLights);
        }

        // 创建辅助线
        const axesHelperAttr = {
            show: false,
            length: 100
        }
        if(this.axesHelperAttr){
            this.axesHelperAttr = Object.assign(axesHelperAttr, this.axesHelperAttr)
        }else{
            this.axesHelperAttr = axesHelperAttr
        }
        if(this.axesHelperAttr.show){
            this.axesHelper = this.createAxesHelper(this.axesHelperAttr.length)
            this.scene.add(this.axesHelper);
        }

        // 创建轨道控制
        const controlAttr = {
            show: false
        }
        if(this.controlAttr){
            this.controlAttr = Object.assign(controlAttr, this.controlAttr)
        }else{
            this.controlAttr = controlAttr
        }
        if(this.controlAttr.show){
            this.createControl(this.camera, this.dom);
        }

        // 创建点、线
        console.time('a')
        this.initPointLineData()
        if(this.pointsAttr?.length){
            // 点geometry、material
            // let pointGeometry = null
            // let pointMaterial = null
            // let pointmMesh = null
            // 线geometry、material
            let lineMaterial = null
            if(this.isSameNormalStyle === undefined){
                this.isSameNormalStyle = true
                // pointGeometry = this.createSphereGeometry(this.pointAttr.style.normal.geometry);
                // pointMaterial = this.createMeshLambertMaterial(this.pointAttr.style.normal.material);
                // pointmMesh = this.createMesh({geometry: pointGeometry, materialBasic: pointMaterial});

                lineMaterial = this.createMeshLineMaterial(this.lineAttr.style.normal.material);
            }
            // this.pointsAttr.forEach(pointAttrItem => {
            //     // 创建点Mesh
            //     let mesh = null
            //     if(!this.isSameNormalStyle){
            //         pointGeometry = this.createSphereGeometry(pointAttrItem.style.normal.geometry);
            //         pointMaterial = this.createMeshLambertMaterial(pointAttrItem.style.normal.material);
            //         mesh = this.createMesh({geometry: pointGeometry, materialBasic: pointMaterial});
            //     }else{
            //         mesh = pointmMesh.clone();
            //     }
            //     mesh.position.set(pointAttrItem.position.x, pointAttrItem.position.y, pointAttrItem.position.z);
            //     this.points.push(mesh)
            // })
            this.linesArrt.forEach(lineAttrItem => {
                // 创建线Mesh
                let linePositions = []
                lineAttrItem.forEach(linePoint => {
                    let i = (linePoint.row * this.pointAttr.col) + linePoint.col
                    linePositions.push({
                        ...this.pointsAttr[i].position
                    })
                })
                const lineGeometry = this.createLineGeometry(linePositions);
                // if(!this.isSameNormalStyle){
                //     lineMaterial = this.createMeshLineMaterial(lineAttrItem.style.normal.material);
                // }
                const lineMesh = this.createMesh({geometry: lineGeometry, materialBasic: lineMaterial});
                this.lines.push(lineMesh)
            })

            // this.scene.add(...this.points);
            this.scene.add(...this.lines);
        }
        console.timeEnd('a')

        // 渲染
        this.render()
    }
    initPointLineData() {
        const pointAttr = {
            width: this.w,
            height: Math.floor(this.w / 2),
            row: Math.floor(this.w / 40),
            col: Math.floor(this.w / 20),
            // width: this.w * 2,
            // height: this.w,
            // row: this.w / 20,
            // col: this.w / 10,
            // row: 10,
            // col: 10,
            style: {
                normal: {
                    geometry: {
                        radius: 3,
                        widthSegments: 320,
                        heightSegments: 160,
                    },
                    material: {
                        color: "#ffffff",
                        wireframe: false, //是否将几何体渲染为线框,默认值为false(即渲染为平面多边形)
                    },
                },
                light: {
                    geometry: {
                        radius: 1,
                        widthSegments: 320,
                        heightSegments: 160,
                    },
                    material: {
                        color: "#ffffff",
                        wireframe: false,
                    },
                }
            }
        }
        if(this.pointAttr){
            this.pointAttr = Object.assign(pointAttr, this.pointAttr)
        }else{
            this.pointAttr = pointAttr
        }

        const lineAttr = {
            style: {
                normal: {
                    material: {
                        color: "#fff",
                        // color: "#3587C7",
                        linewidth: 1,
                    },
                },
                light: {
                    material: {
                        color: "#ffffff",
                        linewidth: 1,
                    },
                }
            }
        };
        if(this.lineAttr){
            this.lineAttr = Object.assign(lineAttr, this.lineAttr)
        }else{
            this.lineAttr = lineAttr
        }

        const startX = -this.pointAttr.width / 2
        const startZ = -this.pointAttr.height / 2
        const stepX = this.pointAttr.width / this.pointAttr.col
        const stepZ = this.pointAttr.height / this.pointAttr.row
        const sinXNum = this.pointAttr.row / 4
        const sinZNum = this.pointAttr.col / 4
        for(let i = 0 ; i < this.pointAttr.row; i++){
            for(let j = 0 ; j < this.pointAttr.col; j++){
                const x = startX + j * stepX
                const z = startZ + i * stepZ
                const y = (Math.sin((i % sinXNum / sinXNum * Math.PI * 2)) + Math.sin(((j + i) % sinZNum / sinZNum * Math.PI * 2))) * (this.netMaxY / 2)
                this.pointsAttr.push({
                    row: i,
                    col: j,
                    position: {
                        x, y, z
                    },
                    style: {...this.pointAttr.style}
                })

                if(!this.linesArrt[i]){
                    this.linesArrt[i] = []
                }
                this.linesArrt[i][j] = {
                    row: i,
                    col: j
                }
                if(!this.linesArrt[this.pointAttr.row + j]){
                    this.linesArrt[this.pointAttr.row + j] = []
                }
                this.linesArrt[this.pointAttr.row + j][i] = {
                    row: i,
                    col: j
                }
            }
        }
    }
    render = () => {
        //循环调用
        this.requestAnimationFrame = requestAnimationFrame(this.render);
        this.animation()
        this.renderer.render(this.scene, this.camera);
    }
    unmount = () => {
        cancelAnimationFrame(this.requestAnimationFrame)
    }
    animation = () => {
        const sinXNum = this.pointAttr.row / 4
        const sinZNum = this.pointAttr.col / 4
        const count = this.pointAttr.row * this.pointAttr.col
        const animationSpeed = 10 //值越大越慢
        console.time('b')
        // if(this.animationIndex % 10 === 0){
            this.pointsAttr.forEach((pointAttrItem, pointAttrIndex) => {
                const i = pointAttrItem.row
                const j = pointAttrItem.col
                pointAttrItem.position.y = (Math.sin(((i + this.animationIndex / animationSpeed) % sinXNum / sinXNum * Math.PI * 2)) + Math.sin(((j + i + this.animationIndex / animationSpeed) % sinZNum / sinZNum * Math.PI * 2))) * 30
            })
            this.linesArrt.forEach((lineAttrItem, lineAttrIndex) => {
                let linePositions = []
                lineAttrItem.forEach(linePoint => {
                    let i = (linePoint.row * this.pointAttr.col) + linePoint.col
                    let point = this.pointsAttr[i]
                    linePositions.push({
                        ...point.position
                    })
                })
                const lineGeometry = this.createLineGeometry(linePositions);
                this.updateGeometry(this.lines[lineAttrIndex].geometry, lineGeometry)
            })
        // }
        console.timeEnd('b')
        this.animationIndex++
        this.animationIndex %= count * animationSpeed
    }
    updateGeometry = (geometry, geometry_source) => {
        const att_p = geometry.getAttribute('position');
        const att_ps = geometry_source.getAttribute('position');
        let i = 0;
        while(i < att_p.count){
            att_p.setXYZ( i, att_ps.getX(i), att_ps.getY(i),att_ps.getZ(i) );
            i += 1;
        }
        att_p.needsUpdate = true;
        geometry.computeVertexNormals();
    };
    rand = (n,m) => {
        var c = m - n + 1;
        return Math.floor(Math.random() * c + n);
    }    
    // 以下皆为实体创建方法
    createScene = () => {
        return new THREE.Scene();
    }
    createPerspectiveCamera = ({ fov, aspect, near, far }) => {
        // fov — 摄像机视锥体垂直视野角度
        // aspect — 摄像机视锥体长宽比
        // near — 摄像机视锥体近端面
        // far — 摄像机视锥体远端面
        return new THREE.PerspectiveCamera(fov, aspect, near, far);
    }
    createWebGLRenderer = ({ dom, width, height }) => {
        // renderDom — dom
        // width — 渲染宽度 一般取domclientWidth
        // height — 渲染高度 一般取clientHeight
        if (width === undefined) {
            width = dom.clientWidth;
        }
        if (height === undefined) {
            height = dom.clientHeight;
        }
        const renderer = new THREE.WebGLRenderer();
        renderer.setPixelRatio(window.devicePixelRatio || 1);
        renderer.setClearColor('#fff', 0); //设置背景颜色和透明度
        renderer.setSize(width, height);
        dom.appendChild(renderer.domElement);
    
        return renderer;
    }
    createAmbientLight = ({ color, intensity }) => {
        // color - (可选参数)) 十六进制光照颜色。 缺省值 0xffffff (白色)。
        // intensity - (可选参数) 光照强度。 缺省值 1。
        return new THREE.AmbientLight(color, intensity);
    }
    createPointLight = ({ color, intensity, distance, decay }) => {
        // color - (可选参数)) 十六进制光照颜色。 缺省值 0xffffff (白色)。
        // intensity - (可选参数) 光照强度。 缺省值 1。
        // distance - 这个距离表示从光源到光照强度为0的位置。 当设置为0时,光永远不会消失(距离无穷大)。缺省值 0.
        // decay - 沿着光照距离的衰退量。缺省值 2。
        return new THREE.PointLight(color, intensity, distance, decay);
    }
    createSphereGeometry = ({
        radius,
        widthSegments,
        heightSegments,
        phiStart,
        phiLength,
        thetaStart,
        thetaLength
    }) => {
        /*
            radius — 球体半径,默认为1。
            widthSegments — 水平分段数(沿着经线分段),最小值为3,默认值为32。
            heightSegments — 垂直分段数(沿着纬线分段),最小值为2,默认值为16。
            phiStart — 指定水平(经线)起始角度,默认值为0。。
            phiLength — 指定水平(经线)扫描角度的大小,默认值为 Math.PI * 2。
            thetaStart — 指定垂直(纬线)起始角度,默认值为0。
            thetaLength — 指定垂直(纬线)扫描角度大小,默认值为 Math.PI。
        */
        return new THREE.SphereGeometry(
            radius,
            widthSegments,
            heightSegments,
            phiStart,
            phiLength,
            thetaStart,
            thetaLength
        );
    }
    createMeshLambertMaterial = (data) => {
        return new THREE.MeshLambertMaterial(data);
    }
    createLineGeometry = (points) => {
        // const pointsVector3 = [];
        // for (let i = 0; i < points.length; i++) {
        //     pointsVector3.push(new THREE.Vector3(points[i].x, points[i].y, points[i].z));
        // }
        // const geometry = new THREE.BufferGeometry().setFromPoints(pointsVector3);
        // const line = new MeshLine();
        // line.setGeometry(geometry);
        // return line
        let pointsVector3 = []
        points.forEach(point => {
            pointsVector3.push(new THREE.Vector3(point.x, point.y, point.z))
        })
        let curve = new THREE.CatmullRomCurve3(pointsVector3);
        var CurvePath = new THREE.CurvePath();// 创建CurvePath对象
	    // CurvePath.curves.push(line1, curve, line2);// 插入多段线条
	    CurvePath.curves.push(curve);
        return new THREE.TubeGeometry(CurvePath, points.length * 10, 1, 25, false);
    }
    createMeshLineMaterial = (data) => {
        // return new MeshLineMaterial({
        //     lineWidth: data.linewidth,
        //     color: data.color || "white",
        //     dashArray: data.dashArray || 0,
        //     transparent: true,
        // })
        return new THREE.MeshLambertMaterial({
            color: data.color || "white"
        });
    }
    createMesh = ({geometry, materialBasic}) => {
        return new THREE.Mesh(geometry, materialBasic);
    }
    createAxesHelper = (length) => {
        return new THREE.AxesHelper(length)
    }
    createControl = (camera, dom) => {
        return new OrbitControls(camera, dom);
    };
}

export default NetAnimation

文章来源:https://blog.csdn.net/qq_42231248/article/details/135287776
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。