Three.js基础功能学习十八:智能黑板实现实例五

续上章继续实现智能黑板示例:

使用Vue3+Elementplus+Threejs实现智能黑板,实现基础的几何图形、三维图形、手写板的元素动态绘制效果,并实现数学、物理、化学、地理、生物等课程常见的图形元素及函数图形等。

源码下载地址: 点击下载
效果演示:









一、学习视频

https://www.bilibili.com/video/BV1JT69BUEdD/

二、学科图形绘制功能

2.1数学

  1. mathTools.ts
javascript 复制代码
import { CircleMeshItem } from "@/model/MeshToolItem/2d/CircleMeshItem";
import { EquilateralTriangleMeshItem } from "@/model/MeshToolItem/2d/EquilateralTriangleMeshItem";
import { LineMeshItem } from "@/model/MeshToolItem/2d/LineMeshItem";
import { LineSegmentMeshItem } from "@/model/MeshToolItem/2d/LineSegmentMeshItem";
import { PointMeshItem } from "@/model/MeshToolItem/2d/PointMeshItem";
import { PolygonMeshItem } from "@/model/MeshToolItem/2d/PolygonMeshItem";
import { PolyLineMeshItem } from "@/model/MeshToolItem/2d/PolylineMeshItem";
import { RightTriangleMeshItem } from "@/model/MeshToolItem/2d/RightTriangleMeshItem";
import { RingMeshItem } from "@/model/MeshToolItem/2d/RingMeshItem";
import { SectorMeshItem } from "@/model/MeshToolItem/2d/SectorMeshItem";
import { SquareMeshItem } from "@/model/MeshToolItem/2d/SquareMeshItem";
import { TriangleMeshItem } from "@/model/MeshToolItem/2d/triangleMeshItem";
import { COMMOND_TYPE_2D_MESH } from "../Constant";
import { RectangleMeshItem } from "./RectangleMeshItem";
import type { BaseMeshItem } from "@/model/MeshToolItem/BaseMeshItem";
import { CapsuleMeshItem } from "@/model/MeshToolItem/3d/CapsuleMeshItem";
import { ConeMeshItem } from "@/model/MeshToolItem/3d/ConeMeshItem";
import { CylinderMeshItem } from "@/model/MeshToolItem/3d/CylinderMeshItem";
import { Rectangle3DMeshItem } from "@/model/MeshToolItem/3d/Rectangle3DMeshItem";
import { SphereMeshItem } from "@/model/MeshToolItem/3d/SphereMeshItem";
import { Square3DMeshItem } from "@/model/MeshToolItem/3d/Square3DMeshItem";
import { Tetrahedron12MeshItem } from "@/model/MeshToolItem/3d/Tetrahedron12MeshItem";
import { Tetrahedron20MeshItem } from "@/model/MeshToolItem/3d/Tetrahedron20MeshItem";
import { Tetrahedron8MeshItem } from "@/model/MeshToolItem/3d/Tetrahedron8MeshItem";
import { TetrahedronMeshItem } from "@/model/MeshToolItem/3d/TetrahedronMeshItem";
import { TetrahedronXMeshItem } from "@/model/MeshToolItem/3d/TetrahedronXMeshItem";
import { TorusMeshItem } from "@/model/MeshToolItem/3d/TorusMeshItem";
import { SinMeshItem } from "@/model/MeshToolItem/math/SinMeshItem";
import { CosMeshItem } from "@/model/MeshToolItem/math/CosMeshItem";
import { TanMeshItem } from "@/model/MeshToolItem/math/TanMeshItem";
import {  ExpMeshItem } from "@/model/MeshToolItem/math/ExpMeshItem";
import { LogMehsItem } from "@/model/MeshToolItem/math/LogMehsItem";
import { SqrtMeshItem } from "@/model/MeshToolItem/math/SqrtMeshItem";
import { X2MeshItem } from "@/model/MeshToolItem/math/X2MeshItem";
import { X3MeshItem } from "@/model/MeshToolItem/math/X3MeshItem";

const tools = [{
    name: '几何图形',
    icon: '',
    commond: '3d',
    key: '2d',
    fkey: 'math',
    children: new Array<BaseMeshItem>()
}, {
    name: '函数相关',
    icon: '',
    commond: '3d',
    key: '2d',
    fkey: 'math',
    children: new Array<BaseMeshItem>()
}]
export const initTools = ()=>{
    tools[0].children.length = 0;
    tools[0].children.push(...[
        new PointMeshItem('点','point.svg','point','math'),
        new LineMeshItem('直线','line.svg','line','math'),
        new PolyLineMeshItem('折线','polyline.svg','polyline','math'),
        new LineSegmentMeshItem('线段','line_segment.svg','line_segment','math'),

        new CircleMeshItem('圆','circle.svg','circle','math'),
        new SectorMeshItem('扇形','sector.svg','sector','math'),
        new RingMeshItem('环形','ring.svg','ring','math'),

        new SquareMeshItem('正方形','square.svg','square','math'),
        new RectangleMeshItem('长方形','rectangle.svg','rectangle','math'),
        new PolygonMeshItem('多边形','polygon.svg','polygon','math'),

        new TriangleMeshItem('三角形','triangle.svg','triangle','math'),
        new RightTriangleMeshItem('直角三角形','right_triangle.svg','right_triangle','math'),
        new EquilateralTriangleMeshItem('等边三角形','equilateral_triangle.svg','equilateral_triangle','math'),

        new Square3DMeshItem('正方体','cube.svg','cube','math'),
        new Rectangle3DMeshItem('长方体','cuboid.svg','cuboid','math'),
        new TetrahedronMeshItem('四面体','tetrahedron.svg','tetrahedron','math'),
        new Tetrahedron8MeshItem('八面体','tetrahedron8.svg','tetrahedron8','math'),
        new Tetrahedron12MeshItem('十二面体','tetrahedron12.svg','tetrahedron12','math'),
        new Tetrahedron20MeshItem('二十面体','tetrahedron20.svg','tetrahedron20','math'),
        new TetrahedronXMeshItem('多面体','tetrahedronx.svg','tetrahedronx','math'),

        new SphereMeshItem('球体','sphere.svg','sphere','math'),
        new TorusMeshItem('圆环','3d_ring.svg','3d_ring','math'),

        new CylinderMeshItem('圆柱','cylinder.svg','cylinder','math'),
        new CapsuleMeshItem('胶囊','capsule.svg','capsule','math'),

        new ConeMeshItem('锥体','cone.svg','cone','math'),
    ]);
    //数学函数
    tools[1].children.length = 0;
    tools[1].children.push(...[
        new SinMeshItem('SIN','sin.svg','sin','math'),
        new CosMeshItem('Cos','sin.svg','sin','math'),
        new TanMeshItem('Tan','sin.svg','sin','math'),

        new ExpMeshItem('指数函数','exp.svg','exp','math'),
        new LogMehsItem('指数函数','log.svg','log','math'),
        new SqrtMeshItem('平方根函数','sqrt.svg','sqrt','math'),
        new X2MeshItem('二次函数函数','x2.svg','x2','math'),
        new X3MeshItem('三次函数函数','x3.svg','x3','math'),
        
    ]);
}

/**
 * 数学相关图形的定义
 */
export default tools;
  1. CosMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_2D_MESH } from "@/common/Constant";
import { Base2dMeshItem } from "../Base2dMeshItem";
import * as THREE from "three"
import { useConfigStore } from "@/stores/config";
import { ToolBarMeshColorItemConfigItem, ToolBarMeshItemConfigItem, ToolBarMeshMaterialItemConfigItem} from "@/model/ToolItem/ToolBarMeshItem";
import type { OptionData } from "@/model/OptionData";

export class ToolBarMeshSizeItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,value,mesh.item.config.width.value), 3 ) );
    }
}
export class ToolBarMeshWidthItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,mesh.item.config.size.value,value), 3 ) );
    }
}

/**
 * Cos
 */
export class CosMeshItem extends Base2dMeshItem{
    initPoint:THREE.Vector3;

    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.material = this._material;

        this.mesh = this._mesh

        this.mouseMove = this._mouseMove;
      
        this.config = {
            currentMaterial: new ToolBarMeshMaterialItemConfigItem('select','材质',['currentMaterial', 'value'],THREE.LineBasicMaterial,true,true,undefined,undefined,undefined,[{
                value: THREE.LineBasicMaterial,
                label: '实线'
            }, {
                value: THREE.LineDashedMaterial,
                label: '虚线'
            }]),
            size:new ToolBarMeshSizeItemConfigItem('slider','大小',['size', 'value'],1,true,true,0.01,10,0.01),
            width:new ToolBarMeshWidthItemConfigItem('slider','范围',['width', 'value'],1,true,true,1,100,1),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,true),
        }
    }

    private _material (){
        let that = this as Base2dMeshItem;
        if(!that.config){
            return null;
        }
        let color = (that.config && that.config.color) ? that.config.color.value : useConfigStore().d3Config.mesh.line.color;
        if (that.config && that.config.currentMaterial && that.config.currentMaterial.value) {
            return new that.config.currentMaterial.value({
                color: color,
                lineWidth: 1
            });
        } else {
            return new THREE.LineBasicMaterial({
                color: color,
                lineWidth: 1
            });
        }
    }

    protected _mesh(point:THREE.Vector3){
        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);

        const geometry = this.geometry?this.geometry():this._geometry();

        let size = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.mesh.line.width;
        let width = (this.config && this.config.width) ? this.config.width.value : useConfigStore().d3Config.mesh.line.width;
        
        // let points = [point.x,point.y,point.z+0.1,...this.processY(point.x,point.y,point.z,size)];

        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.processY(point.x,point.y,point.z,size,width), 3 ) );

        const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let mesh = new THREE.Line(geometry, material);

        point.z += 0.1;
        mesh.position.copy(point);

        return mesh;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent){
        if(!mesh){
            return;
        }
        point.z += 0.1;
        mesh.position.copy(point);

        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);
    }

    private processY(x:number,y:number,z:number,size:number,width:number){
        let result = [];
        for(let i=-width * Math.PI;i<width * Math.PI;i= i+0.1){
            const pixelX = x + i * size;
            const pixelY = y - Math.cos(i) * size;

            result.push(pixelX,pixelY,z);
        }
        return result;
    }
}
  1. ExpMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_2D_MESH } from "@/common/Constant";
import { Base2dMeshItem } from "../Base2dMeshItem";
import * as THREE from "three"
import { useConfigStore } from "@/stores/config";
import { ToolBarMeshColorItemConfigItem, ToolBarMeshItemConfigItem, ToolBarMeshMaterialItemConfigItem} from "@/model/ToolItem/ToolBarMeshItem";
import type { OptionData } from "@/model/OptionData";

export class ToolBarMeshSizeItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,value,mesh.item.config.width.value), 3 ) );
    }
}
export class ToolBarMeshWidthItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,mesh.item.config.size.value,value), 3 ) );
    }
}

/**
 * 指数函数
 */
export class ExpMeshItem extends Base2dMeshItem{
    initPoint:THREE.Vector3;

    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.material = this._material;

        this.mesh = this._mesh

        this.mouseMove = this._mouseMove;
      
        this.config = {
            currentMaterial: new ToolBarMeshMaterialItemConfigItem('select','材质',['currentMaterial', 'value'],THREE.LineBasicMaterial,true,true,undefined,undefined,undefined,[{
                value: THREE.LineBasicMaterial,
                label: '实线'
            }, {
                value: THREE.LineDashedMaterial,
                label: '虚线'
            }]),
            size:new ToolBarMeshSizeItemConfigItem('slider','大小',['size', 'value'],1,true,true,0.01,10,0.01),
            width:new ToolBarMeshWidthItemConfigItem('slider','范围',['width', 'value'],1,true,true,1,100,1),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,true),
        }
    }

    private _material (){
        let that = this as Base2dMeshItem;
        if(!that.config){
            return null;
        }
        let color = (that.config && that.config.color) ? that.config.color.value : useConfigStore().d3Config.mesh.line.color;
        if (that.config && that.config.currentMaterial && that.config.currentMaterial.value) {
            return new that.config.currentMaterial.value({
                color: color,
                lineWidth: 1
            });
        } else {
            return new THREE.LineBasicMaterial({
                color: color,
                lineWidth: 1
            });
        }
    }

    protected _mesh(point:THREE.Vector3){
        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);

        const geometry = this.geometry?this.geometry():this._geometry();

        let size = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.mesh.line.width;
        let width = (this.config && this.config.width) ? this.config.width.value : useConfigStore().d3Config.mesh.line.width;
        
        // let points = [point.x,point.y,point.z+0.1,...this.processY(point.x,point.y,point.z,size)];

        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.processY(point.x,point.y,point.z,size,width), 3 ) );

        const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let mesh = new THREE.Line(geometry, material);

        point.z += 0.1;
        mesh.position.copy(point);

        return mesh;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent){
        if(!mesh){
            return;
        }
        point.z += 0.1;
        mesh.position.copy(point);

        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);
    }

    private processY(x:number,y:number,z:number,size:number,width:number){
        let result = [];
        for(let i=-width ;i<width ;i= i+0.1){
            const pixelX = x + i * size;
            const pixelY = y - Math.exp(i) * size;

            result.push(pixelX,pixelY,z);
        }
        return result;
    }
}
  1. LogMehsItem.ts
javascript 复制代码
import { COMMOND_TYPE_2D_MESH } from "@/common/Constant";
import { Base2dMeshItem } from "../Base2dMeshItem";
import * as THREE from "three"
import { useConfigStore } from "@/stores/config";
import { ToolBarMeshColorItemConfigItem, ToolBarMeshItemConfigItem, ToolBarMeshMaterialItemConfigItem} from "@/model/ToolItem/ToolBarMeshItem";
import type { OptionData } from "@/model/OptionData";

export class ToolBarMeshSizeItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,value,mesh.item.config.width.value), 3 ) );
    }
}
export class ToolBarMeshWidthItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,mesh.item.config.size.value,value), 3 ) );
    }
}

/**
 * 对数函数
 */
export class LogMehsItem extends Base2dMeshItem{
    initPoint:THREE.Vector3;

    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.material = this._material;

        this.mesh = this._mesh

        this.mouseMove = this._mouseMove;
      
        this.config = {
            currentMaterial: new ToolBarMeshMaterialItemConfigItem('select','材质',['currentMaterial', 'value'],THREE.LineBasicMaterial,true,true,undefined,undefined,undefined,[{
                value: THREE.LineBasicMaterial,
                label: '实线'
            }, {
                value: THREE.LineDashedMaterial,
                label: '虚线'
            }]),
            size:new ToolBarMeshSizeItemConfigItem('slider','大小',['size', 'value'],1,true,true,0.01,10,0.01),
            width:new ToolBarMeshWidthItemConfigItem('slider','范围',['width', 'value'],1,true,true,1,100,1),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,true),
        }
    }

    private _material (){
        let that = this as Base2dMeshItem;
        if(!that.config){
            return null;
        }
        let color = (that.config && that.config.color) ? that.config.color.value : useConfigStore().d3Config.mesh.line.color;
        if (that.config && that.config.currentMaterial && that.config.currentMaterial.value) {
            return new that.config.currentMaterial.value({
                color: color,
                lineWidth: 1
            });
        } else {
            return new THREE.LineBasicMaterial({
                color: color,
                lineWidth: 1
            });
        }
    }

    protected _mesh(point:THREE.Vector3){
        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);

        const geometry = this.geometry?this.geometry():this._geometry();

        let size = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.mesh.line.width;
        let width = (this.config && this.config.width) ? this.config.width.value : useConfigStore().d3Config.mesh.line.width;
        
        // let points = [point.x,point.y,point.z+0.1,...this.processY(point.x,point.y,point.z,size)];

        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.processY(point.x,point.y,point.z,size,width), 3 ) );

        const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let mesh = new THREE.Line(geometry, material);

        point.z += 0.1;
        mesh.position.copy(point);

        return mesh;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent){
        if(!mesh){
            return;
        }
        point.z += 0.1;
        mesh.position.copy(point);

        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);
    }

    private processY(x:number,y:number,z:number,size:number,width:number){
        let result = [];
        for(let i=0.1 ;i<width ;i= i+0.1){
            const pixelX = x + i * size;
            const pixelY = y - Math.log(i) * size;

            result.push(pixelX,pixelY,z);
        }
        return result;
    }
}
  1. SinMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_2D_MESH } from "@/common/Constant";
import { Base2dMeshItem } from "../Base2dMeshItem";
import * as THREE from "three"
import { useConfigStore } from "@/stores/config";
import { ToolBarMeshColorItemConfigItem, ToolBarMeshItemConfigItem, ToolBarMeshMaterialItemConfigItem} from "@/model/ToolItem/ToolBarMeshItem";
import type { OptionData } from "@/model/OptionData";

export class ToolBarMeshSizeItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,value,mesh.item.config.width.value), 3 ) );
    }
}
export class ToolBarMeshWidthItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,mesh.item.config.size.value,value), 3 ) );
    }
}

/**
 * Sin
 */
export class SinMeshItem extends Base2dMeshItem{
    initPoint:THREE.Vector3;

    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.material = this._material;

        this.mesh = this._mesh

        this.mouseMove = this._mouseMove;
      
        this.config = {
            currentMaterial: new ToolBarMeshMaterialItemConfigItem('select','材质',['currentMaterial', 'value'],THREE.LineBasicMaterial,true,true,undefined,undefined,undefined,[{
                value: THREE.LineBasicMaterial,
                label: '实线'
            }, {
                value: THREE.LineDashedMaterial,
                label: '虚线'
            }]),
            size:new ToolBarMeshSizeItemConfigItem('slider','大小',['size', 'value'],1,true,true,0.01,10,0.01),
            width:new ToolBarMeshWidthItemConfigItem('slider','范围',['width', 'value'],1,true,true,1,100,1),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,true),
        }
    }

    private _material (){
        let that = this as Base2dMeshItem;
        if(!that.config){
            return null;
        }
        let color = (that.config && that.config.color) ? that.config.color.value : useConfigStore().d3Config.mesh.line.color;
        if (that.config && that.config.currentMaterial && that.config.currentMaterial.value) {
            return new that.config.currentMaterial.value({
                color: color,
                lineWidth: 1
            });
        } else {
            return new THREE.LineBasicMaterial({
                color: color,
                lineWidth: 1
            });
        }
    }

    protected _mesh(point:THREE.Vector3){
        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);

        const geometry = this.geometry?this.geometry():this._geometry();

        let size = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.mesh.line.width;
        let width = (this.config && this.config.width) ? this.config.width.value : useConfigStore().d3Config.mesh.line.width;
        
        // let points = [point.x,point.y,point.z+0.1,...this.processY(point.x,point.y,point.z,size)];

        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.processY(point.x,point.y,point.z,size,width), 3 ) );

        const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let mesh = new THREE.Line(geometry, material);

        point.z += 0.1;
        mesh.position.copy(point);

        return mesh;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent){
        if(!mesh){
            return;
        }
        point.z += 0.1;
        mesh.position.copy(point);

        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);
    }

    private processY(x:number,y:number,z:number,size:number,width:number){
        let result = [];
        for(let i=-width * Math.PI;i<width * Math.PI;i= i+0.1){
            const pixelX = x + i * size;
            const pixelY = y - Math.sin(i) * size;

            result.push(pixelX,pixelY,z);
        }
        return result;
    }
}
  1. SqrtMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_2D_MESH } from "@/common/Constant";
import { Base2dMeshItem } from "../Base2dMeshItem";
import * as THREE from "three"
import { useConfigStore } from "@/stores/config";
import { ToolBarMeshColorItemConfigItem, ToolBarMeshItemConfigItem, ToolBarMeshMaterialItemConfigItem} from "@/model/ToolItem/ToolBarMeshItem";
import type { OptionData } from "@/model/OptionData";

export class ToolBarMeshSizeItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,value,mesh.item.config.width.value), 3 ) );
    }
}
export class ToolBarMeshWidthItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,mesh.item.config.size.value,value), 3 ) );
    }
}

/**
 * 平方根
 */
export class SqrtMeshItem extends Base2dMeshItem{
    initPoint:THREE.Vector3;

    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.material = this._material;

        this.mesh = this._mesh

        this.mouseMove = this._mouseMove;
      
        this.config = {
            currentMaterial: new ToolBarMeshMaterialItemConfigItem('select','材质',['currentMaterial', 'value'],THREE.LineBasicMaterial,true,true,undefined,undefined,undefined,[{
                value: THREE.LineBasicMaterial,
                label: '实线'
            }, {
                value: THREE.LineDashedMaterial,
                label: '虚线'
            }]),
            size:new ToolBarMeshSizeItemConfigItem('slider','大小',['size', 'value'],1,true,true,0.01,10,0.01),
            width:new ToolBarMeshWidthItemConfigItem('slider','范围',['width', 'value'],1,true,true,1,100,1),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,true),
        }
    }

    private _material (){
        let that = this as Base2dMeshItem;
        if(!that.config){
            return null;
        }
        let color = (that.config && that.config.color) ? that.config.color.value : useConfigStore().d3Config.mesh.line.color;
        if (that.config && that.config.currentMaterial && that.config.currentMaterial.value) {
            return new that.config.currentMaterial.value({
                color: color,
                lineWidth: 1
            });
        } else {
            return new THREE.LineBasicMaterial({
                color: color,
                lineWidth: 1
            });
        }
    }

    protected _mesh(point:THREE.Vector3){
        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);

        const geometry = this.geometry?this.geometry():this._geometry();

        let size = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.mesh.line.width;
        let width = (this.config && this.config.width) ? this.config.width.value : useConfigStore().d3Config.mesh.line.width;
        
        // let points = [point.x,point.y,point.z+0.1,...this.processY(point.x,point.y,point.z,size)];

        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.processY(point.x,point.y,point.z,size,width), 3 ) );

        const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let mesh = new THREE.Line(geometry, material);

        point.z += 0.1;
        mesh.position.copy(point);

        return mesh;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent){
        if(!mesh){
            return;
        }
        point.z += 0.1;
        mesh.position.copy(point);

        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);
    }

    private processY(x:number,y:number,z:number,size:number,width:number){
        let result = [];
        for(let i=0 ;i<width ;i= i+0.1){
            const pixelX = x + i * size;
            const pixelY = y - Math.sqrt(i) * size;

            result.push(pixelX,pixelY,z);
        }
        return result;
    }
}
  1. TanMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_2D_MESH } from "@/common/Constant";
import { Base2dMeshItem } from "../Base2dMeshItem";
import * as THREE from "three"
import { useConfigStore } from "@/stores/config";
import { ToolBarMeshColorItemConfigItem, ToolBarMeshItemConfigItem, ToolBarMeshMaterialItemConfigItem} from "@/model/ToolItem/ToolBarMeshItem";
import type { OptionData } from "@/model/OptionData";

export class ToolBarMeshSizeItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,value,mesh.item.config.width.value), 3 ) );
    }
}
export class ToolBarMeshWidthItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,mesh.item.config.size.value,value), 3 ) );
    }
}

/**
 * Tan
 */
export class TanMeshItem extends Base2dMeshItem{
    initPoint:THREE.Vector3;

    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.material = this._material;

        this.mesh = this._mesh

        this.mouseMove = this._mouseMove;
      
        this.config = {
            currentMaterial: new ToolBarMeshMaterialItemConfigItem('select','材质',['currentMaterial', 'value'],THREE.LineBasicMaterial,true,true,undefined,undefined,undefined,[{
                value: THREE.LineBasicMaterial,
                label: '实线'
            }, {
                value: THREE.LineDashedMaterial,
                label: '虚线'
            }]),
            size:new ToolBarMeshSizeItemConfigItem('slider','大小',['size', 'value'],1,true,true,0.01,10,0.01),
            width:new ToolBarMeshWidthItemConfigItem('slider','范围',['width', 'value'],1,true,true,1,100,1),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,true),
        }
    }

    private _material (){
        let that = this as Base2dMeshItem;
        if(!that.config){
            return null;
        }
        let color = (that.config && that.config.color) ? that.config.color.value : useConfigStore().d3Config.mesh.line.color;
        if (that.config && that.config.currentMaterial && that.config.currentMaterial.value) {
            return new that.config.currentMaterial.value({
                color: color,
                lineWidth: 1
            });
        } else {
            return new THREE.LineBasicMaterial({
                color: color,
                lineWidth: 1
            });
        }
    }

    protected _mesh(point:THREE.Vector3){
        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);

        const geometry = this.geometry?this.geometry():this._geometry();

        let size = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.mesh.line.width;
        let width = (this.config && this.config.width) ? this.config.width.value : useConfigStore().d3Config.mesh.line.width;
        
        // let points = [point.x,point.y,point.z+0.1,...this.processY(point.x,point.y,point.z,size)];

        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.processY(point.x,point.y,point.z,size,width), 3 ) );

        const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let mesh = new THREE.Line(geometry, material);

        point.z += 0.1;
        mesh.position.copy(point);

        return mesh;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent){
        if(!mesh){
            return;
        }
        point.z += 0.1;
        mesh.position.copy(point);

        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);
    }

    private processY(x:number,y:number,z:number,size:number,width:number){
        let result = [];
        for(let i=-width * Math.PI;i<width * Math.PI;i= i+0.1){
            const pixelX = x + i * size;
            const pixelY = y - Math.tan(i) * size;

            result.push(pixelX,pixelY,z);
        }
        return result;
    }
}
  1. X2MeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_2D_MESH } from "@/common/Constant";
import { Base2dMeshItem } from "../Base2dMeshItem";
import * as THREE from "three"
import { useConfigStore } from "@/stores/config";
import { ToolBarMeshColorItemConfigItem, ToolBarMeshItemConfigItem, ToolBarMeshMaterialItemConfigItem} from "@/model/ToolItem/ToolBarMeshItem";
import type { OptionData } from "@/model/OptionData";

export class ToolBarMeshSizeItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,value,mesh.item.config.width.value), 3 ) );
    }
}
export class ToolBarMeshWidthItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,mesh.item.config.size.value,value), 3 ) );
    }
}

/**
 * 二次函数
 */
export class X2MeshItem extends Base2dMeshItem{
    initPoint:THREE.Vector3;

    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.material = this._material;

        this.mesh = this._mesh

        this.mouseMove = this._mouseMove;
      
        this.config = {
            currentMaterial: new ToolBarMeshMaterialItemConfigItem('select','材质',['currentMaterial', 'value'],THREE.LineBasicMaterial,true,true,undefined,undefined,undefined,[{
                value: THREE.LineBasicMaterial,
                label: '实线'
            }, {
                value: THREE.LineDashedMaterial,
                label: '虚线'
            }]),
            size:new ToolBarMeshSizeItemConfigItem('slider','大小',['size', 'value'],1,true,true,0.01,10,0.01),
            width:new ToolBarMeshWidthItemConfigItem('slider','范围',['width', 'value'],1,true,true,1,100,1),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,true),
        }
    }

    private _material (){
        let that = this as Base2dMeshItem;
        if(!that.config){
            return null;
        }
        let color = (that.config && that.config.color) ? that.config.color.value : useConfigStore().d3Config.mesh.line.color;
        if (that.config && that.config.currentMaterial && that.config.currentMaterial.value) {
            return new that.config.currentMaterial.value({
                color: color,
                lineWidth: 1
            });
        } else {
            return new THREE.LineBasicMaterial({
                color: color,
                lineWidth: 1
            });
        }
    }

    protected _mesh(point:THREE.Vector3){
        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);

        const geometry = this.geometry?this.geometry():this._geometry();

        let size = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.mesh.line.width;
        let width = (this.config && this.config.width) ? this.config.width.value : useConfigStore().d3Config.mesh.line.width;
        
        // let points = [point.x,point.y,point.z+0.1,...this.processY(point.x,point.y,point.z,size)];

        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.processY(point.x,point.y,point.z,size,width), 3 ) );

        const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let mesh = new THREE.Line(geometry, material);

        point.z += 0.1;
        mesh.position.copy(point);

        return mesh;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent){
        if(!mesh){
            return;
        }
        point.z += 0.1;
        mesh.position.copy(point);

        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);
    }

    private processY(x:number,y:number,z:number,size:number,width:number){
        let result = [];
        for(let i= -width ;i<width ;i= i+0.1){
            const pixelX = x + i * size;
            const pixelY = y - (i*i) * size;

            result.push(pixelX,pixelY,z);
        }
        return result;
    }
}
  1. X3MeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_2D_MESH } from "@/common/Constant";
import { Base2dMeshItem } from "../Base2dMeshItem";
import * as THREE from "three"
import { useConfigStore } from "@/stores/config";
import { ToolBarMeshColorItemConfigItem, ToolBarMeshItemConfigItem, ToolBarMeshMaterialItemConfigItem} from "@/model/ToolItem/ToolBarMeshItem";
import type { OptionData } from "@/model/OptionData";

export class ToolBarMeshSizeItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,value,mesh.item.config.width.value), 3 ) );
    }
}
export class ToolBarMeshWidthItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,mesh.item.config.size.value,value), 3 ) );
    }
}

/**
 * 三次函数
 */
export class X3MeshItem extends Base2dMeshItem{
    initPoint:THREE.Vector3;

    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.material = this._material;

        this.mesh = this._mesh

        this.mouseMove = this._mouseMove;
      
        this.config = {
            currentMaterial: new ToolBarMeshMaterialItemConfigItem('select','材质',['currentMaterial', 'value'],THREE.LineBasicMaterial,true,true,undefined,undefined,undefined,[{
                value: THREE.LineBasicMaterial,
                label: '实线'
            }, {
                value: THREE.LineDashedMaterial,
                label: '虚线'
            }]),
            size:new ToolBarMeshSizeItemConfigItem('slider','大小',['size', 'value'],1,true,true,0.01,10,0.01),
            width:new ToolBarMeshWidthItemConfigItem('slider','范围',['width', 'value'],1,true,true,1,100,1),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,true),
        }
    }

    private _material (){
        let that = this as Base2dMeshItem;
        if(!that.config){
            return null;
        }
        let color = (that.config && that.config.color) ? that.config.color.value : useConfigStore().d3Config.mesh.line.color;
        if (that.config && that.config.currentMaterial && that.config.currentMaterial.value) {
            return new that.config.currentMaterial.value({
                color: color,
                lineWidth: 1
            });
        } else {
            return new THREE.LineBasicMaterial({
                color: color,
                lineWidth: 1
            });
        }
    }

    protected _mesh(point:THREE.Vector3){
        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);

        const geometry = this.geometry?this.geometry():this._geometry();

        let size = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.mesh.line.width;
        let width = (this.config && this.config.width) ? this.config.width.value : useConfigStore().d3Config.mesh.line.width;
        
        // let points = [point.x,point.y,point.z+0.1,...this.processY(point.x,point.y,point.z,size)];

        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.processY(point.x,point.y,point.z,size,width), 3 ) );

        const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let mesh = new THREE.Line(geometry, material);

        point.z += 0.1;
        mesh.position.copy(point);

        return mesh;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent){
        if(!mesh){
            return;
        }
        point.z += 0.1;
        mesh.position.copy(point);

        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);
    }

    private processY(x:number,y:number,z:number,size:number,width:number){
        let result = [];
        for(let i= -width ;i<width ;i= i+0.1){
            const pixelX = x + i * size;
            const pixelY = y - (i*i*i) * size;

            result.push(pixelX,pixelY,z);
        }
        return result;
    }
}

2.2物理

  1. physicsTools.ts
javascript 复制代码
import { VoltageMeshItem } from "@/model/MeshToolItem/physics/VoltageMeshItem";
import { COMMOND_TYPE_2D_MESH } from "../Constant";
import type { BaseMeshItem } from "@/model/MeshToolItem/BaseMeshItem";
import { SecondLawMeshItem } from "@/model/MeshToolItem/physics/SecondLawMeshItem";
import { HookeLawMeshItem } from "@/model/MeshToolItem/physics/HookeLawMeshItem";
import { CoulombsLawMeshItem } from "@/model/MeshToolItem/physics/CoulombsLawMeshItem";
import { SpeedMeshItem } from "@/model/MeshToolItem/physics/SpeedMeshItem";
import { EngieMeshItem } from "@/model/MeshToolItem/physics/EngieMeshItem";
/**
 * 物理相关图形的定义
 */
const tools =  [ {
    name: '电磁相关',
    icon: '',
    commond: '3d',
    key: '2d',
    fkey: 'physics',
    children: new Array<BaseMeshItem>()
}, {
    name: '光学相关',
    icon: '',
    commond: '3d',
    key: '2d',
    fkey: 'physics',
    children: new Array<BaseMeshItem>()
}, {
    name: '力学相关',
    icon: '',
    commond: '3d',
    key: '2d',
    fkey: 'physics',
    children: new Array<BaseMeshItem>()
}]


export const initTools = ()=>{
    tools[0].children.length = 0;
    tools[0].children.push(...[
        new VoltageMeshItem('欧姆定律','voltage.svg','voltage','math'),
    ]);
    tools[1].children.length = 0;
    tools[1].children.push(...[
        new SpeedMeshItem('光速公式','speed.svg','speed','math'),
        new EngieMeshItem('光子能量','engie.svg','engie','math'),
        
    ]);
    tools[2].children.length = 0;
    tools[2].children.push(...[
        new SecondLawMeshItem('牛顿第二定律','second.svg','second','math'),
        new HookeLawMeshItem('胡克定律','second.svg','second','math'),
        new CoulombsLawMeshItem('库仑定律','second.svg','second','math'),
    ]);
}
export default tools;
  1. CoulombsLawMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_2D_MESH } from "@/common/Constant";
import { Base2dMeshItem } from "../Base2dMeshItem";
import * as THREE from "three"
import { useConfigStore } from "@/stores/config";
import { ToolBarMeshColorItemConfigItem, ToolBarMeshItemConfigItem, ToolBarMeshMaterialItemConfigItem} from "@/model/ToolItem/ToolBarMeshItem";
import type { OptionData } from "@/model/OptionData";

export class ToolBarMeshSizeItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,value,mesh.item.config.width.value), 3 ) );
    }
}
export class ToolBarMeshWidthItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,mesh.item.config.size.value,value), 3 ) );
    }
}

/**
 * 库仑定律图表
 */
export class CoulombsLawMeshItem extends Base2dMeshItem{
    initPoint:THREE.Vector3;

    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.material = this._material;

        this.mesh = this._mesh

        this.mouseMove = this._mouseMove;
      
        this.config = {
            currentMaterial: new ToolBarMeshMaterialItemConfigItem('select','材质',['currentMaterial', 'value'],THREE.LineBasicMaterial,true,true,undefined,undefined,undefined,[{
                value: THREE.LineBasicMaterial,
                label: '实线'
            }, {
                value: THREE.LineDashedMaterial,
                label: '虚线'
            }]),
            size:new ToolBarMeshSizeItemConfigItem('slider','电荷',['size', 'value'],1,true,true,0.01,10,0.01),
            width:new ToolBarMeshWidthItemConfigItem('slider','距离',['width', 'value'],1,true,true,1,100,1),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,true),
        }
    }

    private _material (){
        let that = this as Base2dMeshItem;
        if(!that.config){
            return null;
        }
        let color = (that.config && that.config.color) ? that.config.color.value : useConfigStore().d3Config.mesh.line.color;
        if (that.config && that.config.currentMaterial && that.config.currentMaterial.value) {
            return new that.config.currentMaterial.value({
                color: color,
                lineWidth: 1
            });
        } else {
            return new THREE.LineBasicMaterial({
                color: color,
                lineWidth: 1
            });
        }
    }

    protected _mesh(point:THREE.Vector3){
        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);

        const geometry = this.geometry?this.geometry():this._geometry();

        let size = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.mesh.line.width;
        let width = (this.config && this.config.width) ? this.config.width.value : useConfigStore().d3Config.mesh.line.width;
        
        // let points = [point.x,point.y,point.z+0.1,...this.processY(point.x,point.y,point.z,size)];

        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.processY(point.x,point.y,point.z,size,width), 3 ) );

        const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let mesh = new THREE.Line(geometry, material);

        point.z += 0.1;
        mesh.position.copy(point);

        return mesh;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent){
        if(!mesh){
            return;
        }
        point.z += 0.1;
        mesh.position.copy(point);

        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);
    }

    private processY(x:number,y:number,z:number,c:number,a:number){
        let result = [];
        for(let i=0;i<c;i= i+0.1){
            const pixelX = x + i * a;
            const pixelY = y - ((9e9*i*i)/(a*a)) * a;

            result.push(pixelX,pixelY,z);
        }
        return result;
    }
}
  1. EngieMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_2D_MESH } from "@/common/Constant";
import { Base2dMeshItem } from "../Base2dMeshItem";
import * as THREE from "three"
import { useConfigStore } from "@/stores/config";
import { ToolBarMeshColorItemConfigItem, ToolBarMeshItemConfigItem, ToolBarMeshMaterialItemConfigItem} from "@/model/ToolItem/ToolBarMeshItem";
import type { OptionData } from "@/model/OptionData";

export class ToolBarMeshWidthItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,3.14,value), 3 ) );
    }
}

/**
 * 光子能量
 */
export class EngieMeshItem extends Base2dMeshItem{
    initPoint:THREE.Vector3;

    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.material = this._material;

        this.mesh = this._mesh

        this.mouseMove = this._mouseMove;
      
        this.config = {
            currentMaterial: new ToolBarMeshMaterialItemConfigItem('select','材质',['currentMaterial', 'value'],THREE.LineBasicMaterial,true,true,undefined,undefined,undefined,[{
                value: THREE.LineBasicMaterial,
                label: '实线'
            }, {
                value: THREE.LineDashedMaterial,
                label: '虚线'
            }]),
            // size:new ToolBarMeshSizeItemConfigItem('slider','波长',['size', 'value'],1,true,true,0.01,10,0.01),
            width:new ToolBarMeshWidthItemConfigItem('slider','频率',['width', 'value'],1,true,true,1,100,1),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,true),
        }
    }

    private _material (){
        let that = this as Base2dMeshItem;
        if(!that.config){
            return null;
        }
        let color = (that.config && that.config.color) ? that.config.color.value : useConfigStore().d3Config.mesh.line.color;
        if (that.config && that.config.currentMaterial && that.config.currentMaterial.value) {
            return new that.config.currentMaterial.value({
                color: color,
                lineWidth: 1
            });
        } else {
            return new THREE.LineBasicMaterial({
                color: color,
                lineWidth: 1
            });
        }
    }

    protected _mesh(point:THREE.Vector3){
        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);

        const geometry = this.geometry?this.geometry():this._geometry();

        // let size = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.mesh.line.width;
        let width = (this.config && this.config.width) ? this.config.width.value : useConfigStore().d3Config.mesh.line.width;
        
        // let points = [point.x,point.y,point.z+0.1,...this.processY(point.x,point.y,point.z,size)];

        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.processY(point.x,point.y,point.z,3.14,width), 3 ) );

        const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let mesh = new THREE.Line(geometry, material);

        point.z += 0.1;
        mesh.position.copy(point);

        return mesh;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent){
        if(!mesh){
            return;
        }
        point.z += 0.1;
        mesh.position.copy(point);

        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);
    }

    private processY(x:number,y:number,z:number,c:number,a:number){
        let result = [];
        for(let i=0;i<c;i= i+0.1){
            const pixelX = x + i * a;
            const pixelY = y - (i*a) * a;

            result.push(pixelX,pixelY,z);
        }
        return result;
    }
}
  1. HookeLawMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_2D_MESH } from "@/common/Constant";
import { Base2dMeshItem } from "../Base2dMeshItem";
import * as THREE from "three"
import { useConfigStore } from "@/stores/config";
import { ToolBarMeshColorItemConfigItem, ToolBarMeshItemConfigItem, ToolBarMeshMaterialItemConfigItem} from "@/model/ToolItem/ToolBarMeshItem";
import type { OptionData } from "@/model/OptionData";

export class ToolBarMeshSizeItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,value,mesh.item.config.width.value), 3 ) );
    }
}
export class ToolBarMeshWidthItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,mesh.item.config.size.value,value), 3 ) );
    }
}

/**
 * 胡克定律图表
 */
export class HookeLawMeshItem extends Base2dMeshItem{
    initPoint:THREE.Vector3;

    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.material = this._material;

        this.mesh = this._mesh

        this.mouseMove = this._mouseMove;
      
        this.config = {
            currentMaterial: new ToolBarMeshMaterialItemConfigItem('select','材质',['currentMaterial', 'value'],THREE.LineBasicMaterial,true,true,undefined,undefined,undefined,[{
                value: THREE.LineBasicMaterial,
                label: '实线'
            }, {
                value: THREE.LineDashedMaterial,
                label: '虚线'
            }]),
            size:new ToolBarMeshSizeItemConfigItem('slider','常数',['size', 'value'],1,true,true,0.01,10,0.01),
            width:new ToolBarMeshWidthItemConfigItem('slider','距离',['width', 'value'],1,true,true,1,100,1),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,true),
        }
    }

    private _material (){
        let that = this as Base2dMeshItem;
        if(!that.config){
            return null;
        }
        let color = (that.config && that.config.color) ? that.config.color.value : useConfigStore().d3Config.mesh.line.color;
        if (that.config && that.config.currentMaterial && that.config.currentMaterial.value) {
            return new that.config.currentMaterial.value({
                color: color,
                lineWidth: 1
            });
        } else {
            return new THREE.LineBasicMaterial({
                color: color,
                lineWidth: 1
            });
        }
    }

    protected _mesh(point:THREE.Vector3){
        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);

        const geometry = this.geometry?this.geometry():this._geometry();

        let size = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.mesh.line.width;
        let width = (this.config && this.config.width) ? this.config.width.value : useConfigStore().d3Config.mesh.line.width;
        
        // let points = [point.x,point.y,point.z+0.1,...this.processY(point.x,point.y,point.z,size)];

        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.processY(point.x,point.y,point.z,size,width), 3 ) );

        const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let mesh = new THREE.Line(geometry, material);

        point.z += 0.1;
        mesh.position.copy(point);

        return mesh;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent){
        if(!mesh){
            return;
        }
        point.z += 0.1;
        mesh.position.copy(point);

        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);
    }

    private processY(x:number,y:number,z:number,k:number,a:number){
        let result = [];
        for(let i=0;i<k;i= i+0.1){
            const pixelX = x + i * a;
            const pixelY = y - (i*a) * a;

            result.push(pixelX,pixelY,z);
        }
        return result;
    }
}
  1. SecondLawMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_2D_MESH } from "@/common/Constant";
import { Base2dMeshItem } from "../Base2dMeshItem";
import * as THREE from "three"
import { useConfigStore } from "@/stores/config";
import { ToolBarMeshColorItemConfigItem, ToolBarMeshItemConfigItem, ToolBarMeshMaterialItemConfigItem} from "@/model/ToolItem/ToolBarMeshItem";
import type { OptionData } from "@/model/OptionData";

export class ToolBarMeshSizeItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,value,mesh.item.config.width.value), 3 ) );
    }
}
export class ToolBarMeshWidthItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,mesh.item.config.size.value,value), 3 ) );
    }
}

/**
 * 牛顿第二定律图表
 */
export class SecondLawMeshItem extends Base2dMeshItem{
    initPoint:THREE.Vector3;

    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.material = this._material;

        this.mesh = this._mesh

        this.mouseMove = this._mouseMove;
      
        this.config = {
            currentMaterial: new ToolBarMeshMaterialItemConfigItem('select','材质',['currentMaterial', 'value'],THREE.LineBasicMaterial,true,true,undefined,undefined,undefined,[{
                value: THREE.LineBasicMaterial,
                label: '实线'
            }, {
                value: THREE.LineDashedMaterial,
                label: '虚线'
            }]),
            size:new ToolBarMeshSizeItemConfigItem('slider','质量',['size', 'value'],1,true,true,0.01,10,0.01),
            width:new ToolBarMeshWidthItemConfigItem('slider','加速度',['width', 'value'],1,true,true,1,100,1),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,true),
        }
    }

    private _material (){
        let that = this as Base2dMeshItem;
        if(!that.config){
            return null;
        }
        let color = (that.config && that.config.color) ? that.config.color.value : useConfigStore().d3Config.mesh.line.color;
        if (that.config && that.config.currentMaterial && that.config.currentMaterial.value) {
            return new that.config.currentMaterial.value({
                color: color,
                lineWidth: 1
            });
        } else {
            return new THREE.LineBasicMaterial({
                color: color,
                lineWidth: 1
            });
        }
    }

    protected _mesh(point:THREE.Vector3){
        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);

        const geometry = this.geometry?this.geometry():this._geometry();

        let size = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.mesh.line.width;
        let width = (this.config && this.config.width) ? this.config.width.value : useConfigStore().d3Config.mesh.line.width;
        
        // let points = [point.x,point.y,point.z+0.1,...this.processY(point.x,point.y,point.z,size)];

        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.processY(point.x,point.y,point.z,size,width), 3 ) );

        const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let mesh = new THREE.Line(geometry, material);

        point.z += 0.1;
        mesh.position.copy(point);

        return mesh;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent){
        if(!mesh){
            return;
        }
        point.z += 0.1;
        mesh.position.copy(point);

        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);
    }

    private processY(x:number,y:number,z:number,m:number,a:number){
        let result = [];
        for(let i=0;i<m;i= i+0.1){
            const pixelX = x + i * a;
            const pixelY = y - (i*a) * a;

            result.push(pixelX,pixelY,z);
        }
        return result;
    }
}
  1. SpeedMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_2D_MESH } from "@/common/Constant";
import { Base2dMeshItem } from "../Base2dMeshItem";
import * as THREE from "three"
import { useConfigStore } from "@/stores/config";
import { ToolBarMeshColorItemConfigItem, ToolBarMeshItemConfigItem, ToolBarMeshMaterialItemConfigItem} from "@/model/ToolItem/ToolBarMeshItem";
import type { OptionData } from "@/model/OptionData";

export class ToolBarMeshSizeItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,value,mesh.item.config.width.value), 3 ) );
    }
}
export class ToolBarMeshWidthItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,mesh.item.config.size.value,value), 3 ) );
    }
}

/**
 * 光速
 */
export class SpeedMeshItem extends Base2dMeshItem{
    initPoint:THREE.Vector3;

    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.material = this._material;

        this.mesh = this._mesh

        this.mouseMove = this._mouseMove;
      
        this.config = {
            currentMaterial: new ToolBarMeshMaterialItemConfigItem('select','材质',['currentMaterial', 'value'],THREE.LineBasicMaterial,true,true,undefined,undefined,undefined,[{
                value: THREE.LineBasicMaterial,
                label: '实线'
            }, {
                value: THREE.LineDashedMaterial,
                label: '虚线'
            }]),
            size:new ToolBarMeshSizeItemConfigItem('slider','波长',['size', 'value'],1,true,true,0.01,10,0.01),
            width:new ToolBarMeshWidthItemConfigItem('slider','频率',['width', 'value'],1,true,true,1,100,1),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,true),
        }
    }

    private _material (){
        let that = this as Base2dMeshItem;
        if(!that.config){
            return null;
        }
        let color = (that.config && that.config.color) ? that.config.color.value : useConfigStore().d3Config.mesh.line.color;
        if (that.config && that.config.currentMaterial && that.config.currentMaterial.value) {
            return new that.config.currentMaterial.value({
                color: color,
                lineWidth: 1
            });
        } else {
            return new THREE.LineBasicMaterial({
                color: color,
                lineWidth: 1
            });
        }
    }

    protected _mesh(point:THREE.Vector3){
        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);

        const geometry = this.geometry?this.geometry():this._geometry();

        let size = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.mesh.line.width;
        let width = (this.config && this.config.width) ? this.config.width.value : useConfigStore().d3Config.mesh.line.width;
        
        // let points = [point.x,point.y,point.z+0.1,...this.processY(point.x,point.y,point.z,size)];

        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.processY(point.x,point.y,point.z,size,width), 3 ) );

        const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let mesh = new THREE.Line(geometry, material);

        point.z += 0.1;
        mesh.position.copy(point);

        return mesh;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent){
        if(!mesh){
            return;
        }
        point.z += 0.1;
        mesh.position.copy(point);

        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);
    }

    private processY(x:number,y:number,z:number,c:number,a:number){
        let result = [];
        for(let i=0;i<c;i= i+0.1){
            const pixelX = x + i * a;
            const pixelY = y - (i*a) * a;

            result.push(pixelX,pixelY,z);
        }
        return result;
    }
}
  1. VoltageMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_2D_MESH } from "@/common/Constant";
import { Base2dMeshItem } from "../Base2dMeshItem";
import * as THREE from "three"
import { useConfigStore } from "@/stores/config";
import { ToolBarMeshColorItemConfigItem, ToolBarMeshItemConfigItem, ToolBarMeshMaterialItemConfigItem} from "@/model/ToolItem/ToolBarMeshItem";
import type { OptionData } from "@/model/OptionData";

export class ToolBarMeshSizeItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,value,mesh.item.config.width.value), 3 ) );
    }
}
export class ToolBarMeshWidthItemConfigItem extends ToolBarMeshItemConfigItem<number>{
    constructor(
        type: string,
        name: string,
        modelPath: string[],
        value: number,
        auto: boolean= false,
        form: boolean = false,
        min?: number,
        max?: number,
        step?: number,
        options?: OptionData[]
    ){
        super(type,
        name,
        modelPath,
        value,
        auto,
        form,
        min,
        max,
        step,
        options);
    }

    updateConfig(mesh:THREE.Mesh, value:number) {
        mesh.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( mesh.item.processY(mesh.item.initPoint.x,mesh.item.initPoint.y,mesh.item.initPoint.z,mesh.item.config.size.value,value), 3 ) );
    }
}

/**
 * 欧姆定律
 */
export class VoltageMeshItem extends Base2dMeshItem{
    initPoint:THREE.Vector3;

    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.material = this._material;

        this.mesh = this._mesh

        this.mouseMove = this._mouseMove;
      
        this.config = {
            currentMaterial: new ToolBarMeshMaterialItemConfigItem('select','材质',['currentMaterial', 'value'],THREE.LineBasicMaterial,true,true,undefined,undefined,undefined,[{
                value: THREE.LineBasicMaterial,
                label: '实线'
            }, {
                value: THREE.LineDashedMaterial,
                label: '虚线'
            }]),
            size:new ToolBarMeshSizeItemConfigItem('slider','电压',['size', 'value'],1,true,true,0.01,10,0.01),
            width:new ToolBarMeshWidthItemConfigItem('slider','电阻',['width', 'value'],1,true,true,1,100,1),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,true),
        }
    }

    private _material (){
        let that = this as Base2dMeshItem;
        if(!that.config){
            return null;
        }
        let color = (that.config && that.config.color) ? that.config.color.value : useConfigStore().d3Config.mesh.line.color;
        if (that.config && that.config.currentMaterial && that.config.currentMaterial.value) {
            return new that.config.currentMaterial.value({
                color: color,
                lineWidth: 1
            });
        } else {
            return new THREE.LineBasicMaterial({
                color: color,
                lineWidth: 1
            });
        }
    }

    protected _mesh(point:THREE.Vector3){
        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);

        const geometry = this.geometry?this.geometry():this._geometry();

        let size = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.mesh.line.width;
        let width = (this.config && this.config.width) ? this.config.width.value : useConfigStore().d3Config.mesh.line.width;
        
        // let points = [point.x,point.y,point.z+0.1,...this.processY(point.x,point.y,point.z,size)];

        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.processY(point.x,point.y,point.z,size,width), 3 ) );

        const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let mesh = new THREE.Line(geometry, material);

        point.z += 0.1;
        mesh.position.copy(point);

        return mesh;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent){
        if(!mesh){
            return;
        }
        point.z += 0.1;
        mesh.position.copy(point);

        this.initPoint = new THREE.Vector3(point.x,point.y,point.z);
    }

    private processY(x:number,y:number,z:number,voltage:number,resistance:number){
        let result = [];
        for(let i=0;i<voltage;i= i+0.1){
            const pixelX = x + i * resistance;
            const pixelY = y - (i/resistance) * resistance;

            result.push(pixelX,pixelY,z);
        }
        return result;
    }
}

2.3化学

  1. chemistryTools.ts
javascript 复制代码
import type { BaseMeshItem } from "@/model/MeshToolItem/BaseMeshItem";
import { COMMOND_TYPE_2D_MESH } from "../Constant";
import { Co2MeshItem } from "@/model/MeshToolItem/chemistry/Co2MeshItem";
import { CMeshItem } from "@/model/MeshToolItem/chemistry/CMeshItem";
/**
 * 化学相关图形的定义
 */
const tools = [ {
    name: '分子',
    icon: '',
    commond: '3d',
    key: '2d',
    fkey: 'chemistry',
    children: new Array<BaseMeshItem>()
}, {
    name: '原子',
    icon: '',
    commond: '3d',
    key: '2d',
    fkey: 'chemistry',
    children: new Array<BaseMeshItem>()
}]

export const initTools = ()=>{
    tools[0].children.length = 0;
    tools[0].children.push(...[
        new Co2MeshItem('二氧化碳','co2.svg','co2','math'),
    ])
    tools[1].children.length = 0;
    tools[1].children.push(...[
        new CMeshItem('碳原子','c.svg','c','math'),
    ])
}

export default tools;
  1. CMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_3D_MESH } from "@/common/Constant";
import { Base3dMeshItem } from "../Base3dMeshItem";
import * as THREE from "three"
import { ToolBarMeshColorItemConfigItem, ToolBarMeshMaterialItemConfigItem, ToolBarMeshRadiusItemConfigItem, ToolBarMeshTextureItemConfigItem, type ToolBarMeshItem } from "@/model/ToolItem/ToolBarMeshItem";
import { useConfigStore } from "@/stores/config";

/**
 * 碳原子
 */
export class CMeshItem extends Base3dMeshItem{
    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.geometry = this._geometry;

        this.material = this._material;

        this.mouseMove = this._mouseMove;
        
        this.config = {
            radius:new ToolBarMeshRadiusItemConfigItem('slider','原子核半径',['radius', 'value'],0.5,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            size:new ToolBarMeshRadiusItemConfigItem('slider','电子半径',['size', 'value'],0.1,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            color:new ToolBarMeshColorItemConfigItem('color','原子核颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,false),
            color1:new ToolBarMeshColorItemConfigItem('color','电子颜色',['color1', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#e93e3e'),true,false),
        }
    }

    protected _geometry(){
        let that = this as Base3dMeshItem;
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        return new THREE.SphereGeometry(radius,132,132);
    }

    private _material (){
        let that = this as ToolBarMeshItem;
        let color = (that.config && that.config.color) ? that.config.color.value : new THREE.Color('#ffffff');
        return new THREE.MeshBasicMaterial({ color: color ,});
    }

    protected _mesh(point:THREE.Vector3) {
        // const geometry = this.geometry?this.geometry():this._geometry();
        // geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [point.x,point.y,point.z+0.1], 3 ) );
        // const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let result = new THREE.Group();

        let radius = (this.config && this.config.radius) ? this.config.radius.value : useConfigStore().d3Config.camera.near;
        let geometry = new THREE.SphereGeometry(radius,132,132);

        let color = (this.config && this.config.color) ? this.config.color.value : new THREE.Color('#ffffff');

        let o = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ color: color ,}))
        o.position.set(point.x,point.y,point.z+0.1);
        result.add(o);

        radius = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.camera.near;
        geometry = new THREE.SphereGeometry(radius,132,132);
        color = (this.config && this.config.color1) ? this.config.color1.value : new THREE.Color('#ca3636');

        for(let i=0;i<6;i++){
            let c = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ color: new THREE.Color('#ca3636') ,}))

            const x = point.x + 2 * Math.cos(60 * i);
            const y = point.y + 2 * Math.sin(60 * i);

            c.position.set(x,y,point.z+0.1);
            result.add(c);
        }

        return result;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent) {
        mesh.position.copy(point);
    }

}
  1. Co2MeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_3D_MESH } from "@/common/Constant";
import { Base3dMeshItem } from "../Base3dMeshItem";
import * as THREE from "three"
import { ToolBarMeshColorItemConfigItem, ToolBarMeshMaterialItemConfigItem, ToolBarMeshRadiusItemConfigItem, ToolBarMeshTextureItemConfigItem, type ToolBarMeshItem } from "@/model/ToolItem/ToolBarMeshItem";
import { useConfigStore } from "@/stores/config";

/**
 * 二氧化碳
 */
export class Co2MeshItem extends Base3dMeshItem{
    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.geometry = this._geometry;

        this.material = this._material;

        this.mouseMove = this._mouseMove;
        
        this.config = {
            radius:new ToolBarMeshRadiusItemConfigItem('slider','碳原子半径',['radius', 'value'],0.6,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            size:new ToolBarMeshRadiusItemConfigItem('slider','氧原子半径',['size', 'value'],0.5,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,false),
            color1:new ToolBarMeshColorItemConfigItem('color','颜色',['color1', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#e93e3e'),true,false),
        }
    }

    protected _geometry(){
        let that = this as Base3dMeshItem;
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        return new THREE.SphereGeometry(radius,132,132);
    }

    private _material (){
        let that = this as ToolBarMeshItem;
        let color = (that.config && that.config.color) ? that.config.color.value : new THREE.Color('#ffffff');
        return new THREE.MeshBasicMaterial({ color: color ,});
    }

    protected _mesh(point:THREE.Vector3) {
        // const geometry = this.geometry?this.geometry():this._geometry();
        // geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [point.x,point.y,point.z+0.1], 3 ) );
        // const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let result = new THREE.Group();

        let radius = (this.config && this.config.radius) ? this.config.radius.value : useConfigStore().d3Config.camera.near;
        let geometry = new THREE.SphereGeometry(radius,132,132);

        let color = (this.config && this.config.color) ? this.config.color.value : new THREE.Color('#ffffff');

        let o = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ color: color ,}))
        o.position.set(point.x+0.9,point.y,point.z+0.1);
        result.add(o);

        radius = (this.config && this.config.size) ? this.config.size.value : useConfigStore().d3Config.camera.near;
        geometry = new THREE.SphereGeometry(radius,132,132);
        color = (this.config && this.config.color1) ? this.config.color1.value : new THREE.Color('#ca3636');

        let c = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ color: new THREE.Color('#ca3636') ,}))
        c.position.set(point.x,point.y+1.2,point.z+0.1);
        result.add(c);

        c = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ color: new THREE.Color('#ca3636') ,}))
        c.position.set(point.x,point.y-1.2,point.z+0.1);
        result.add(c);

        return result;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent) {
        mesh.position.copy(point);
    }

}

2.4生物

  1. biologyTools.ts
javascript 复制代码
import { DnaMeshItem } from "@/model/MeshToolItem/biology/DnaMeshItem";
import { COMMOND_TYPE_2D_MESH } from "../Constant";
/**
 * 生物相关图形的定义
 */
const tools = [ {
    name: '常见',
    icon: '',
    commond: '3d',
    key: '2d',
    fkey: 'biology',
    children: new Array<BaseMeshItem>()
}]


export const initTools = ()=>{
    tools[0].children.length = 0;
    tools[0].children.push(...[
        new DnaMeshItem('DNA','dna.svg','dna','math'),
    ])
}

export default tools;
  1. DnaMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_3D_MESH } from "@/common/Constant";
import { Base3dMeshItem } from "../Base3dMeshItem";
import * as THREE from "three"
import { ToolBarMeshColorItemConfigItem, ToolBarMeshMaterialItemConfigItem, ToolBarMeshRadiusItemConfigItem, ToolBarMeshTextureItemConfigItem, type ToolBarMeshItem } from "@/model/ToolItem/ToolBarMeshItem";
import { useConfigStore } from "@/stores/config";

/**
 * DNA结构
 */
export class DnaMeshItem extends Base3dMeshItem{
    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.geometry = this._geometry;

        this.material = this._material;

        this.mouseMove = this._mouseMove;
        
        this.config = {
            radius:new ToolBarMeshRadiusItemConfigItem('slider','原子核半径',['radius', 'value'],0.5,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            color:new ToolBarMeshColorItemConfigItem('color','原子核颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,false),
        }
    }

    protected _geometry(){
        let that = this as Base3dMeshItem;
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        return new THREE.SphereGeometry(radius,132,132);
    }

    private _material (){
        let that = this as ToolBarMeshItem;
        let color = (that.config && that.config.color) ? that.config.color.value : new THREE.Color('#ffffff');
        return new THREE.MeshBasicMaterial({ color: color ,});
    }

    protected _mesh(point:THREE.Vector3) {
        // const geometry = this.geometry?this.geometry():this._geometry();
        // geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [point.x,point.y,point.z+0.1], 3 ) );
        // const material = this.material?this.material():new THREE.MeshBasicMaterial();

        let result = new THREE.Group();

        let radius = (this.config && this.config.radius) ? this.config.radius.value : useConfigStore().d3Config.camera.near;
        let geometry = new THREE.SphereGeometry(radius,132,132);

        let color = (this.config && this.config.color) ? this.config.color.value : new THREE.Color('#ffffff');

        this.createDNAStructure(2, 100, 1.2, 1.0,result,new THREE.CylinderGeometry(0.05, 0.05, 0.3, 8),new THREE.MeshPhongMaterial({ color: 0x333333, shininess: 80 }),new THREE.SphereGeometry(0.15, 12, 12));

        return result;
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent) {
        mesh.position.copy(point);
    }

    // 绘制双螺旋
    protected createDNAStructure(turns = 5, baseCount = 40, radius = 0.2, pitch = 1.0,dnaGroup:THREE.Group,backboneGeometry:THREE.CylinderGeometry,backboneMaterial:THREE.MeshPhongMaterial,baseGeometry:THREE.SphereGeometry) {
      dnaGroup.clear();

      const baseMaterials = {
        A: new THREE.MeshPhongMaterial({ color: 0x00ff99, shininess: 60 }),
        T: new THREE.MeshPhongMaterial({ color: 0xff6666, shininess: 60 }),
        G: new THREE.MeshPhongMaterial({ color: 0x6666ff, shininess: 60 }),
        C: new THREE.MeshPhongMaterial({ color: 0xffff66, shininess: 60 })
        };

      const angleStep = (2 * Math.PI * turns) / baseCount;
      const heightStep = pitch / baseCount;

      // 生成碱基对序列(随机 A-T, G-C 配对)
      const basePairs = [];
      for (let i = 0; i < baseCount; i++) {
        const pair = Math.random() > 0.5 ? ['A', 'T'] : ['G', 'C'];
        basePairs.push(pair);
      }

        const offsetAngle = Math.PI / 2;

      // 绘制两条螺旋骨架和碱基对
      for (let i = 0; i < baseCount; i++) {
        const angle = i * angleStep;
        const height = i * heightStep;

        // 左右螺旋的偏移角度
        const x1 = radius * Math.cos(angle);
        const y1 = height;
        const z1 = radius * Math.sin(angle);
        const x2 = radius * Math.cos(angle + offsetAngle);
        const y2 = height;
        const z2 = radius * Math.sin(angle + offsetAngle);

        // 创建骨架段
        const backbone1 = new THREE.Mesh(backboneGeometry, backboneMaterial);
        const backbone2 = new THREE.Mesh(backboneGeometry, backboneMaterial);
        backbone1.position.set(x1, y1, z1);
        backbone2.position.set(x2, y2, z2);

        // 旋转骨架以对齐螺旋切线
        const dir1 = new THREE.Vector3(
          -radius * Math.sin(angle),
          heightStep,
          radius * Math.cos(angle)
        ).normalize();
        const dir2 = new THREE.Vector3(
          -radius * Math.sin(angle + offsetAngle),
          heightStep,
          radius * Math.cos(angle + offsetAngle)
        ).normalize();

        backbone1.lookAt(new THREE.Vector3(x1 + dir1.x, y1 + dir1.y, z1 + dir1.z));
        backbone2.lookAt(new THREE.Vector3(x2 + dir2.x, y2 + dir2.y, z2 + dir2.z));

        dnaGroup.add(backbone1);
        dnaGroup.add(backbone2);

        // 创建碱基对
        const [base1, base2] = basePairs[i];
        const base1Mesh = new THREE.Mesh(baseGeometry, baseMaterials[base1]);
        const base2Mesh = new THREE.Mesh(baseGeometry, baseMaterials[base2]);

        base1Mesh.position.set(x1, y1, z1);
        base2Mesh.position.set(x2, y2, z2);

        // 碱基对朝向彼此
        base1Mesh.lookAt(x2, y2, z2);
        base2Mesh.lookAt(x1, y1, z1);

        dnaGroup.add(base1Mesh);
        dnaGroup.add(base2Mesh);
      }

      
        // 添加连接线(可选,增强视觉)
        for (let i = 0; i < baseCount; i++) {
            const angle = i * angleStep;
            const height = i * heightStep;
            const x1 = radius * Math.cos(angle);
            const z1 = radius * Math.sin(angle);
            const x2 = radius * Math.cos(angle + offsetAngle);
            const z2 = radius * Math.sin(angle + offsetAngle);

            const lineGeometry = new THREE.BufferGeometry().setFromPoints([
            new THREE.Vector3(x1, height, z1),
            new THREE.Vector3(x2, height, z2)
            ]);
            const lineMaterial = new THREE.LineBasicMaterial({ color: 0x888888, transparent: true, opacity: 0.4 });
            const line = new THREE.Line(lineGeometry, lineMaterial);
            dnaGroup.add(line);
        }
    }
}

2.5地理

  1. geographyTools.ts
javascript 复制代码
import type { BaseMeshItem } from "@/model/MeshToolItem/BaseMeshItem";
import { COMMOND_TYPE_2D_MESH } from "../Constant";
import { SunMeshItem } from "@/model/MeshToolItem/geography/SunMeshItem";
import { JinMeshItem } from "@/model/MeshToolItem/geography/JinMeshItem";
import { ShuiMeshItem } from "@/model/MeshToolItem/geography/ShuiMeshItem";
import { MuMeshItem } from "@/model/MeshToolItem/geography/MuMeshItem";
import { EarthMeshItem } from "@/model/MeshToolItem/geography/EarthMeshItem";
import { TuMeshItem } from "@/model/MeshToolItem/geography/TuMeshItem";
import { HeiMeshItem } from "@/model/MeshToolItem/geography/HeiMeshItem";
import { TianMeshItem } from "@/model/MeshToolItem/geography/TianMeshItem";
import { MoonMeshItem } from "@/model/MeshToolItem/geography/MoonMeshItem";
import { HuoMeshItem } from "@/model/MeshToolItem/geography/HuoMeshItem";
/**
 * 地理相关图形的定义
 */
const tools = [ {
    name: '太阳系',
    icon: '',
    commond: '3d',
    key: '2d',
    fkey: 'geography',
    children: new Array<BaseMeshItem>()
}, {
    name: '地球',
    icon: '',
    commond: '3d',
    key: '2d',
    fkey: 'geography',
    children: new Array<BaseMeshItem>()
}]


export const initTools = ()=>{
    tools[0].children.length = 0;
    tools[0].children.push(...[
        new SunMeshItem('太阳','sun.svg','sun','math'),
        new ShuiMeshItem('水星','shui.svg','shui','math'),
        new JinMeshItem('金星','jin.svg','jin','math'),
        new MuMeshItem('木星','mu.svg','mu','math'),
        new EarthMeshItem('地球','earth.svg','earth','math'),
        new TuMeshItem('土星','tu.svg','tu','math'),
        new HuoMeshItem('火星','huo.svg','huo','math'),
        new HeiMeshItem('海王星','hei.svg','hei','math'),
        new TianMeshItem('天王星','tian.svg','tian','math'),
        new MoonMeshItem('月亮','moon.svg','moon','math'),
    ])
    tools[1].children.length = 0;
    tools[1].children.push(...[
        new EarthMeshItem('地球','earth.svg','earth','math'),
    ])
}

export default tools;
  1. EarthMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_3D_MESH } from "@/common/Constant";
import { Base3dMeshItem } from "../Base3dMeshItem";
import * as THREE from "three"
import { ToolBarMeshColorItemConfigItem, ToolBarMeshMaterialItemConfigItem, ToolBarMeshRadiusItemConfigItem, ToolBarMeshTextureItemConfigItem, type ToolBarMeshItem } from "@/model/ToolItem/ToolBarMeshItem";
import { useConfigStore } from "@/stores/config";

/**
 * 地球
 */
export class EarthMeshItem extends Base3dMeshItem{
    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.geometry = this._geometry;

        this.material = this._material;

        this.mouseMove = this._mouseMove;
        
        this.config = {
            radius:new ToolBarMeshRadiusItemConfigItem('slider','半径',['radius', 'value'],0.8,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,false),
        }
    }

    protected _geometry(){
        let that = this as Base3dMeshItem;
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        return new THREE.SphereGeometry(radius,132,132);
    }

    private _material (){
        let that = this as ToolBarMeshItem;
        let color = (that.config && that.config.color) ? that.config.color.value : new THREE.Color('#ffffff');
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        
        const loader = new THREE.TextureLoader();
        let texture =  loader.load(new URL(`@/assets/texture/earth.png`, import.meta.url).href);
        return new THREE.MeshBasicMaterial({ color: color,map:texture });
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent) {
        mesh.position.copy(point);
    }

}
  1. HeiMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_3D_MESH } from "@/common/Constant";
import { Base3dMeshItem } from "../Base3dMeshItem";
import * as THREE from "three"
import { ToolBarMeshColorItemConfigItem, ToolBarMeshMaterialItemConfigItem, ToolBarMeshRadiusItemConfigItem, ToolBarMeshTextureItemConfigItem, type ToolBarMeshItem } from "@/model/ToolItem/ToolBarMeshItem";
import { useConfigStore } from "@/stores/config";

/**
 * 海王星
 */
export class HeiMeshItem extends Base3dMeshItem{
    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.geometry = this._geometry;

        this.material = this._material;

        this.mouseMove = this._mouseMove;
        
        this.config = {
            radius:new ToolBarMeshRadiusItemConfigItem('slider','半径',['radius', 'value'],1.2,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,false),
        }
    }

    protected _geometry(){
        let that = this as Base3dMeshItem;
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        return new THREE.SphereGeometry(radius,132,132);
    }

    private _material (){
        let that = this as ToolBarMeshItem;
        let color = (that.config && that.config.color) ? that.config.color.value : new THREE.Color('#ffffff');
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        
        const loader = new THREE.TextureLoader();
        let texture =  loader.load(new URL(`@/assets/texture/hei.png`, import.meta.url).href);
        return new THREE.MeshBasicMaterial({ color: color,map:texture });
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent) {
        mesh.position.copy(point);
    }

}
  1. HuoMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_3D_MESH } from "@/common/Constant";
import { Base3dMeshItem } from "../Base3dMeshItem";
import * as THREE from "three"
import { ToolBarMeshColorItemConfigItem, ToolBarMeshMaterialItemConfigItem, ToolBarMeshRadiusItemConfigItem, ToolBarMeshTextureItemConfigItem, type ToolBarMeshItem } from "@/model/ToolItem/ToolBarMeshItem";
import { useConfigStore } from "@/stores/config";

/**
 * 火星
 */
export class HuoMeshItem extends Base3dMeshItem{
    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.geometry = this._geometry;

        this.material = this._material;

        this.mouseMove = this._mouseMove;
        
        this.config = {
            radius:new ToolBarMeshRadiusItemConfigItem('slider','半径',['radius', 'value'],0.9,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,false),
        }
    }

    protected _geometry(){
        let that = this as Base3dMeshItem;
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        return new THREE.SphereGeometry(radius,132,132);
    }

    private _material (){
        let that = this as ToolBarMeshItem;
        let color = (that.config && that.config.color) ? that.config.color.value : new THREE.Color('#ffffff');
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        
        const loader = new THREE.TextureLoader();
        let texture =  loader.load(new URL(`@/assets/texture/huo.png`, import.meta.url).href);
        return new THREE.MeshBasicMaterial({ color: color,map:texture });
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent) {
        mesh.position.copy(point);
    }

}
  1. JinMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_3D_MESH } from "@/common/Constant";
import { Base3dMeshItem } from "../Base3dMeshItem";
import * as THREE from "three"
import { ToolBarMeshColorItemConfigItem, ToolBarMeshMaterialItemConfigItem, ToolBarMeshRadiusItemConfigItem, ToolBarMeshTextureItemConfigItem, type ToolBarMeshItem } from "@/model/ToolItem/ToolBarMeshItem";
import { useConfigStore } from "@/stores/config";

/**
 * 金星
 */
export class JinMeshItem extends Base3dMeshItem{
    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.geometry = this._geometry;

        this.material = this._material;

        this.mouseMove = this._mouseMove;
        
        this.config = {
            radius:new ToolBarMeshRadiusItemConfigItem('slider','半径',['radius', 'value'],0.8,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,false),
        }
    }

    protected _geometry(){
        let that = this as Base3dMeshItem;
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        return new THREE.SphereGeometry(radius,132,132);
    }

    private _material (){
        let that = this as ToolBarMeshItem;
        let color = (that.config && that.config.color) ? that.config.color.value : new THREE.Color('#ffffff');
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        
        const loader = new THREE.TextureLoader();
        let texture =  loader.load(new URL(`@/assets/texture/jin.png`, import.meta.url).href);
        return new THREE.MeshBasicMaterial({ color: color,map:texture });
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent) {
        mesh.position.copy(point);
    }

}
  1. MoonMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_3D_MESH } from "@/common/Constant";
import { Base3dMeshItem } from "../Base3dMeshItem";
import * as THREE from "three"
import { ToolBarMeshColorItemConfigItem, ToolBarMeshMaterialItemConfigItem, ToolBarMeshRadiusItemConfigItem, ToolBarMeshTextureItemConfigItem, type ToolBarMeshItem } from "@/model/ToolItem/ToolBarMeshItem";
import { useConfigStore } from "@/stores/config";

/**
 * 天王星
 */
export class MoonMeshItem extends Base3dMeshItem{
    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.geometry = this._geometry;

        this.material = this._material;

        this.mouseMove = this._mouseMove;
        
        this.config = {
            radius:new ToolBarMeshRadiusItemConfigItem('slider','半径',['radius', 'value'],0.4,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,false),
        }
    }

    protected _geometry(){
        let that = this as Base3dMeshItem;
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        return new THREE.SphereGeometry(radius,132,132);
    }

    private _material (){
        let that = this as ToolBarMeshItem;
        let color = (that.config && that.config.color) ? that.config.color.value : new THREE.Color('#ffffff');
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        
        const loader = new THREE.TextureLoader();
        let texture =  loader.load(new URL(`@/assets/texture/moon.webp`, import.meta.url).href);
        return new THREE.MeshBasicMaterial({ color: color,map:texture });
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent) {
        mesh.position.copy(point);
    }

}
  1. MuMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_3D_MESH } from "@/common/Constant";
import { Base3dMeshItem } from "../Base3dMeshItem";
import * as THREE from "three"
import { ToolBarMeshColorItemConfigItem, ToolBarMeshMaterialItemConfigItem, ToolBarMeshRadiusItemConfigItem, ToolBarMeshTextureItemConfigItem, type ToolBarMeshItem } from "@/model/ToolItem/ToolBarMeshItem";
import { useConfigStore } from "@/stores/config";

/**
 * 木星
 */
export class MuMeshItem extends Base3dMeshItem{
    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.geometry = this._geometry;

        this.material = this._material;

        this.mouseMove = this._mouseMove;
        
        this.config = {
            radius:new ToolBarMeshRadiusItemConfigItem('slider','半径',['radius', 'value'],2,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,false),
        }
    }

    protected _geometry(){
        let that = this as Base3dMeshItem;
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        return new THREE.SphereGeometry(radius,132,132);
    }

    private _material (){
        let that = this as ToolBarMeshItem;
        let color = (that.config && that.config.color) ? that.config.color.value : new THREE.Color('#ffffff');
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        
        const loader = new THREE.TextureLoader();
        let texture =  loader.load(new URL(`@/assets/texture/mu.png`, import.meta.url).href);
        return new THREE.MeshBasicMaterial({ color: color,map:texture });
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent) {
        mesh.position.copy(point);
    }

}
  1. ShuiMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_3D_MESH } from "@/common/Constant";
import { Base3dMeshItem } from "../Base3dMeshItem";
import * as THREE from "three"
import { ToolBarMeshColorItemConfigItem, ToolBarMeshMaterialItemConfigItem, ToolBarMeshRadiusItemConfigItem, ToolBarMeshTextureItemConfigItem, type ToolBarMeshItem } from "@/model/ToolItem/ToolBarMeshItem";
import { useConfigStore } from "@/stores/config";

/**
 * 水星
 */
export class ShuiMeshItem extends Base3dMeshItem{
    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.geometry = this._geometry;

        this.material = this._material;

        this.mouseMove = this._mouseMove;
        
        this.config = {
            radius:new ToolBarMeshRadiusItemConfigItem('slider','半径',['radius', 'value'],0.5,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,false),
        }
    }

    protected _geometry(){
        let that = this as Base3dMeshItem;
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        return new THREE.SphereGeometry(radius,132,132);
    }

    private _material (){
        let that = this as ToolBarMeshItem;
        let color = (that.config && that.config.color) ? that.config.color.value : new THREE.Color('#ffffff');
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        
        const loader = new THREE.TextureLoader();
        let texture =  loader.load(new URL(`@/assets/texture/shui.png`, import.meta.url).href);
        return new THREE.MeshBasicMaterial({ color: color,map:texture });
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent) {
        mesh.position.copy(point);
    }

}
  1. SunMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_3D_MESH } from "@/common/Constant";
import { Base3dMeshItem } from "../Base3dMeshItem";
import * as THREE from "three"
import { ToolBarMeshColorItemConfigItem, ToolBarMeshMaterialItemConfigItem, ToolBarMeshRadiusItemConfigItem, ToolBarMeshTextureItemConfigItem, type ToolBarMeshItem } from "@/model/ToolItem/ToolBarMeshItem";
import { useConfigStore } from "@/stores/config";

/**
 * 太阳
 */
export class SunMeshItem extends Base3dMeshItem{
    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.geometry = this._geometry;

        this.material = this._material;

        this.mouseMove = this._mouseMove;
        
        this.config = {
            radius:new ToolBarMeshRadiusItemConfigItem('slider','半径',['radius', 'value'],3,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,false),
        }
    }

    protected _geometry(){
        let that = this as Base3dMeshItem;
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        return new THREE.SphereGeometry(radius,132,132);
    }

    private _material (){
        let that = this as ToolBarMeshItem;
        let color = (that.config && that.config.color) ? that.config.color.value : new THREE.Color('#ffffff');
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        
        const loader = new THREE.TextureLoader();
        let texture =  loader.load(new URL(`@/assets/texture/sun.png`, import.meta.url).href);
        return new THREE.MeshBasicMaterial({ color: color,map:texture });
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent) {
        mesh.position.copy(point);
    }

}
  1. TianMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_3D_MESH } from "@/common/Constant";
import { Base3dMeshItem } from "../Base3dMeshItem";
import * as THREE from "three"
import { ToolBarMeshColorItemConfigItem, ToolBarMeshMaterialItemConfigItem, ToolBarMeshRadiusItemConfigItem, ToolBarMeshTextureItemConfigItem, type ToolBarMeshItem } from "@/model/ToolItem/ToolBarMeshItem";
import { useConfigStore } from "@/stores/config";

/**
 * 天王星
 */
export class TianMeshItem extends Base3dMeshItem{
    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.geometry = this._geometry;

        this.material = this._material;

        this.mouseMove = this._mouseMove;
        
        this.config = {
            radius:new ToolBarMeshRadiusItemConfigItem('slider','半径',['radius', 'value'],1.4,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,false),
        }
    }

    protected _geometry(){
        let that = this as Base3dMeshItem;
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        return new THREE.SphereGeometry(radius,132,132);
    }

    private _material (){
        let that = this as ToolBarMeshItem;
        let color = (that.config && that.config.color) ? that.config.color.value : new THREE.Color('#ffffff');
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        
        const loader = new THREE.TextureLoader();
        let texture =  loader.load(new URL(`@/assets/texture/tian.png`, import.meta.url).href);
        return new THREE.MeshBasicMaterial({ color: color,map:texture });
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent) {
        mesh.position.copy(point);
    }

}
  1. TuMeshItem.ts
javascript 复制代码
import { COMMOND_TYPE_3D_MESH } from "@/common/Constant";
import { Base3dMeshItem } from "../Base3dMeshItem";
import * as THREE from "three"
import { ToolBarMeshColorItemConfigItem, ToolBarMeshMaterialItemConfigItem, ToolBarMeshRadiusItemConfigItem, ToolBarMeshTextureItemConfigItem, type ToolBarMeshItem } from "@/model/ToolItem/ToolBarMeshItem";
import { useConfigStore } from "@/stores/config";

/**
 * 土星
 */
export class TuMeshItem extends Base3dMeshItem{
    constructor(name:string,icon:string,key:string,fkey:string){
        super(name,icon,key,fkey);

        this.geometry = this._geometry;

        this.material = this._material;

        this.mouseMove = this._mouseMove;
        
        this.config = {
            radius:new ToolBarMeshRadiusItemConfigItem('slider','半径',['radius', 'value'],0.85,true,false,0,useConfigStore()?.d3Config?.maxSize||8,useConfigStore()?.d3Config?.camera?.near || 0.001),
            color:new ToolBarMeshColorItemConfigItem('color','颜色',['color', 'value'],useConfigStore()?.d3Config?.mesh?.fill?.color || new THREE.Color('#FFFfff'),true,false),
        }
    }

    protected _geometry(){
        let that = this as Base3dMeshItem;
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        return new THREE.SphereGeometry(radius,132,132);
    }

    private _material (){
        let that = this as ToolBarMeshItem;
        let color = (that.config && that.config.color) ? that.config.color.value : new THREE.Color('#ffffff');
        let radius = (that.config && that.config.radius) ? that.config.radius.value : useConfigStore().d3Config.camera.near;
        
        const loader = new THREE.TextureLoader();
        let texture =  loader.load(new URL(`@/assets/texture/tu.png`, import.meta.url).href);
        return new THREE.MeshBasicMaterial({ color: color,map:texture });
    }

    protected _mouseMove(point: THREE.Vector3, mesh: THREE.Mesh,event:MouseEvent) {
        mesh.position.copy(point);
    }

}
相关推荐
恋猫de小郭1 小时前
Android 上为什么主题字体对 Flutter 不生效,对 Compose 生效?Flutter 中文字体问题修复
android·前端·flutter
Moment2 小时前
AI全栈入门指南:一文搞清楚NestJs 中的 Controller 和路由
前端·javascript·后端
禅思院2 小时前
前端架构演进:基于AST的常量模块自动化迁移实践
前端·vue.js·前端框架
程序员马晓博2 小时前
前端并发治理:从 Token 刷新聊起,一个 Promise 就够了
前端·javascript
许杰小刀2 小时前
FastAPI + Vue 前后端分离实战:我的项目结构“避坑指南”
前端·vue.js·fastapi
IT_陈寒2 小时前
Python的asyncio把我整不会了,原来问题出在这儿
前端·人工智能·后端
Unity粉末状在校生2 小时前
清除microsoft edge账户信息
前端·microsoft·edge
walking9572 小时前
Vue3 日历组件选型指南:五大主流方案深度解析
前端·vue.js·面试
木心术12 小时前
设备管理网管系统:详细下一步行动指南
前端·人工智能·opencv