【Threejs效果:挖空几何体】ThreeBSP实现墙体挖洞

2023-11-19

1 效果如下

2 代码如下

基本思路:

 (1) 创建两个mesh,一个墙体,一个窗户

 (2) 然后取墙体和窗户的差集,将差集转换成几何体

 (3) 根据几何体新建mesh,并贴纹理

依赖库有三个:

import * as THREE from 'three';
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import _ThreeBSP  from '../utils/ThreeBSP.js'
// 创建挖墙
  function initObject(){
    // 1 定义墙面
    var cubeGeometry = new THREE.BoxGeometry(1, 10, 30);
    var cube = new THREE.Mesh(cubeGeometry); 
    // 2 定义窗户
    var door = new THREE.BoxGeometry(1, 8, 15);
    var doorMesh = new THREE.Mesh(door);
    doorMesh.position.z = 0
    // 3 定义两个bsp对象
    var cubeBSP = new ThreeBSP(cube);
    var doorBSP = new ThreeBSP(doorMesh);
    // 4 取交集
    let resultBSP = cubeBSP.subtract(doorBSP); // 墙体挖窗户
    // 5 将相交的部分转换成Mesh
    let result = resultBSP.toMesh();
    // 6 转成geometry
    var cubeGeometry = result.geometry
    var cubeMaterial = new THREE.MeshBasicMaterial({
      map:THREE.ImageUtils.loadTexture('./statics/imgs/wall2.jpg')
    })
    // 7 重新生成一个mesh 
    let wallMesh = new THREE.Mesh(cubeGeometry,cubeMaterial);
    scene.add(wallMesh);
}

 本文依赖ThreeBSP这个库;但这个库没有在threejs中集成;所以单独下载下来,然后改成 了ES5的方式;方便我们导入使用;

ThreeBSP.js

'use strict';
	var ThreeBSP, 
		EPSILON = 1e-5,
		COPLANAR = 0,
		FRONT = 1,
		BACK = 2,
		SPANNING = 3;
	
  export default  function( THREE ) {
    var ThreeBSP = function( geometry ) {
      // Convert THREE.Geometry to ThreeBSP
      var i, _length_i,
        face, vertex, faceVertexUvs, uvs,
        polygon,
        polygons = [],
        tree;
    
      if ( geometry instanceof THREE.Geometry ) {
        this.matrix = new THREE.Matrix4;
      } else if ( geometry instanceof THREE.Mesh ) {
        // #todo: add hierarchy support
        geometry.updateMatrix();
        this.matrix = geometry.matrix.clone();
        geometry = geometry.geometry;
      } else if ( geometry instanceof ThreeBSP.Node ) {
        this.tree = geometry;
        this.matrix = new THREE.Matrix4;
        return this;
      } else {
        throw 'ThreeBSP: Given geometry is unsupported';
      }
    
      for ( i = 0, _length_i = geometry.faces.length; i < _length_i; i++ ) {
        face = geometry.faces[i];
        faceVertexUvs = geometry.faceVertexUvs[0][i];
        polygon = new ThreeBSP.Polygon;
        
        if ( face instanceof THREE.Face3 ) {
          vertex = geometry.vertices[ face.a ];
                                  uvs = faceVertexUvs ? new THREE.Vector2( faceVertexUvs[0].x, faceVertexUvs[0].y ) : null;
                                  vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[0], uvs );
          vertex.applyMatrix4(this.matrix);
          polygon.vertices.push( vertex );
          
          vertex = geometry.vertices[ face.b ];
                                  uvs = faceVertexUvs ? new THREE.Vector2( faceVertexUvs[1].x, faceVertexUvs[1].y ) : null;
                                  vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs );
          vertex.applyMatrix4(this.matrix);
          polygon.vertices.push( vertex );
          
          vertex = geometry.vertices[ face.c ];
                                  uvs = faceVertexUvs ? new THREE.Vector2( faceVertexUvs[2].x, faceVertexUvs[2].y ) : null;
                                  vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs );
          vertex.applyMatrix4(this.matrix);
          polygon.vertices.push( vertex );
        } else if ( typeof THREE.Face4 ) {
          vertex = geometry.vertices[ face.a ];
                                  uvs = faceVertexUvs ? new THREE.Vector2( faceVertexUvs[0].x, faceVertexUvs[0].y ) : null;
                                  vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[0], uvs );
          vertex.applyMatrix4(this.matrix);
          polygon.vertices.push( vertex );
          
          vertex = geometry.vertices[ face.b ];
                                  uvs = faceVertexUvs ? new THREE.Vector2( faceVertexUvs[1].x, faceVertexUvs[1].y ) : null;
                                  vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[1], uvs );
          vertex.applyMatrix4(this.matrix);
          polygon.vertices.push( vertex );
          
          vertex = geometry.vertices[ face.c ];
                                  uvs = faceVertexUvs ? new THREE.Vector2( faceVertexUvs[2].x, faceVertexUvs[2].y ) : null;
                                  vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs );
          vertex.applyMatrix4(this.matrix);
          polygon.vertices.push( vertex );
          
          vertex = geometry.vertices[ face.d ];
                                  uvs = faceVertexUvs ? new THREE.Vector2( faceVertexUvs[3].x, faceVertexUvs[3].y ) : null;
                                  vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[3], uvs );
          vertex.applyMatrix4(this.matrix);
          polygon.vertices.push( vertex );
        } else {
          throw 'Invalid face type at index ' + i;
        }
        
        polygon.calculateProperties();
        polygons.push( polygon );
      };
    
      this.tree = new ThreeBSP.Node( polygons );
    };
    ThreeBSP.prototype.subtract = function( other_tree ) {
      var a = this.tree.clone(),
        b = other_tree.tree.clone();
      
      a.invert();
      a.clipTo( b );
      b.clipTo( a );
      b.invert();
      b.clipTo( a );
      b.invert();
      a.build( b.allPolygons() );
      a.invert();
      a = new ThreeBSP( a );
      a.matrix = this.matrix;
      return a;
    };
    ThreeBSP.prototype.union = function( other_tree ) {
      var a = this.tree.clone(),
        b = other_tree.tree.clone();
      
      a.clipTo( b );
      b.clipTo( a );
      b.invert();
      b.clipTo( a );
      b.invert();
      a.build( b.allPolygons() );
      a = new ThreeBSP( a );
      a.matrix = this.matrix;
      return a;
    };
    ThreeBSP.prototype.intersect = function( other_tree ) {
      var a = this.tree.clone(),
        b = other_tree.tree.clone();
      
      a.invert();
      b.clipTo( a );
      b.invert();
      a.clipTo( b );
      b.clipTo( a );
      a.build( b.allPolygons() );
      a.invert();
      a = new ThreeBSP( a );
      a.matrix = this.matrix;
      return a;
    };
    ThreeBSP.prototype.toGeometry = function() {
      var i, j,
        matrix = new THREE.Matrix4().getInverse( this.matrix ),
        geometry = new THREE.Geometry(),
        polygons = this.tree.allPolygons(),
        polygon_count = polygons.length,
        polygon, polygon_vertice_count,
        vertice_dict = {},
        vertex_idx_a, vertex_idx_b, vertex_idx_c,
        vertex, face,
        verticeUvs;
    
      for ( i = 0; i < polygon_count; i++ ) {
        polygon = polygons[i];
        polygon_vertice_count = polygon.vertices.length;
        
        for ( j = 2; j < polygon_vertice_count; j++ ) {
          verticeUvs = [];
          
          vertex = polygon.vertices[0];
          verticeUvs.push( new THREE.Vector2( vertex.uv.x, vertex.uv.y ) );
          vertex = new THREE.Vector3( vertex.x, vertex.y, vertex.z );
          vertex.applyMatrix4(matrix);
          
          if ( typeof vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ] !== 'undefined' ) {
            vertex_idx_a = vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ];
          } else {
            geometry.vertices.push( vertex );
            vertex_idx_a = vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ] = geometry.vertices.length - 1;
          }
          
          vertex = polygon.vertices[j-1];
          verticeUvs.push( new THREE.Vector2( vertex.uv.x, vertex.uv.y ) );
          vertex = new THREE.Vector3( vertex.x, vertex.y, vertex.z );
          vertex.applyMatrix4(matrix);
          if ( typeof vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ] !== 'undefined' ) {
            vertex_idx_b = vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ];
          } else {
            geometry.vertices.push( vertex );
            vertex_idx_b = vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ] = geometry.vertices.length - 1;
          }
          
          vertex = polygon.vertices[j];
          verticeUvs.push( new THREE.Vector2( vertex.uv.x, vertex.uv.y ) );
          vertex = new THREE.Vector3( vertex.x, vertex.y, vertex.z );
          vertex.applyMatrix4(matrix);
          if ( typeof vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ] !== 'undefined' ) {
            vertex_idx_c = vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ];
          } else {
            geometry.vertices.push( vertex );
            vertex_idx_c = vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ] = geometry.vertices.length - 1;
          }
          
          face = new THREE.Face3(
            vertex_idx_a,
            vertex_idx_b,
            vertex_idx_c,
            new THREE.Vector3( polygon.normal.x, polygon.normal.y, polygon.normal.z )
          );
          
          geometry.faces.push( face );
          geometry.faceVertexUvs[0].push( verticeUvs );
        }
        
      }
      return geometry;
    };
    ThreeBSP.prototype.toMesh = function( material ) {
      var geometry = this.toGeometry(),
        mesh = new THREE.Mesh( geometry, material );
      
      mesh.position.setFromMatrixPosition( this.matrix );
      mesh.rotation.setFromRotationMatrix( this.matrix );
      
      return mesh;
    };
    
    
    ThreeBSP.Polygon = function( vertices, normal, w ) {
      if ( !( vertices instanceof Array ) ) {
        vertices = [];
      }
      
      this.vertices = vertices;
      if ( vertices.length > 0 ) {
        this.calculateProperties();
      } else {
        this.normal = this.w = undefined;
      }
    };
    ThreeBSP.Polygon.prototype.calculateProperties = function() {
      var a = this.vertices[0],
        b = this.vertices[1],
        c = this.vertices[2];
        
      this.normal = b.clone().subtract( a ).cross(
        c.clone().subtract( a )
      ).normalize();
      
      this.w = this.normal.clone().dot( a );
      
      return this;
    };
    ThreeBSP.Polygon.prototype.clone = function() {
      var i, vertice_count,
        polygon = new ThreeBSP.Polygon;
      
      for ( i = 0, vertice_count = this.vertices.length; i < vertice_count; i++ ) {
        polygon.vertices.push( this.vertices[i].clone() );
      };
      polygon.calculateProperties();
      
      return polygon;
    };
    
    ThreeBSP.Polygon.prototype.flip = function() {
      var i, vertices = [];
      
      this.normal.multiplyScalar( -1 );
      this.w *= -1;
      
      for ( i = this.vertices.length - 1; i >= 0; i-- ) {
        vertices.push( this.vertices[i] );
      };
      this.vertices = vertices;
      
      return this;
    };
    ThreeBSP.Polygon.prototype.classifyVertex = function( vertex ) {  
      var side_value = this.normal.dot( vertex ) - this.w;
      
      if ( side_value < -EPSILON ) {
        return BACK;
      } else if ( side_value > EPSILON ) {
        return FRONT;
      } else {
        return COPLANAR;
      }
    };
    ThreeBSP.Polygon.prototype.classifySide = function( polygon ) {
      var i, vertex, classification,
        num_positive = 0,
        num_negative = 0,
        vertice_count = polygon.vertices.length;
      
      for ( i = 0; i < vertice_count; i++ ) {
        vertex = polygon.vertices[i];
        classification = this.classifyVertex( vertex );
        if ( classification === FRONT ) {
          num_positive++;
        } else if ( classification === BACK ) {
          num_negative++;
        }
      }
      
      if ( num_positive > 0 && num_negative === 0 ) {
        return FRONT;
      } else if ( num_positive === 0 && num_negative > 0 ) {
        return BACK;
      } else if ( num_positive === 0 && num_negative === 0 ) {
        return COPLANAR;
      } else {
        return SPANNING;
      }
    };
    ThreeBSP.Polygon.prototype.splitPolygon = function( polygon, coplanar_front, coplanar_back, front, back ) {
      var classification = this.classifySide( polygon );
      
      if ( classification === COPLANAR ) {
        
        ( this.normal.dot( polygon.normal ) > 0 ? coplanar_front : coplanar_back ).push( polygon );
        
      } else if ( classification === FRONT ) {
        
        front.push( polygon );
        
      } else if ( classification === BACK ) {
        
        back.push( polygon );
        
      } else {
        
        var vertice_count,
          i, j, ti, tj, vi, vj,
          t, v,
          f = [],
          b = [];
        
        for ( i = 0, vertice_count = polygon.vertices.length; i < vertice_count; i++ ) {
          
          j = (i + 1) % vertice_count;
          vi = polygon.vertices[i];
          vj = polygon.vertices[j];
          ti = this.classifyVertex( vi );
          tj = this.classifyVertex( vj );
          
          if ( ti != BACK ) f.push( vi );
          if ( ti != FRONT ) b.push( vi );
          if ( (ti | tj) === SPANNING ) {
            t = ( this.w - this.normal.dot( vi ) ) / this.normal.dot( vj.clone().subtract( vi ) );
            v = vi.interpolate( vj, t );
            f.push( v );
            b.push( v );
          }
        }
        
        
        if ( f.length >= 3 ) front.push( new ThreeBSP.Polygon( f ).calculateProperties() );
        if ( b.length >= 3 ) back.push( new ThreeBSP.Polygon( b ).calculateProperties() );
      }
    };
    
    ThreeBSP.Vertex = function( x, y, z, normal, uv ) {
      this.x = x;
      this.y = y;
      this.z = z;
      this.normal = normal || new THREE.Vector3;
      this.uv = uv || new THREE.Vector2;
    };
    ThreeBSP.Vertex.prototype.clone = function() {
      return new ThreeBSP.Vertex( this.x, this.y, this.z, this.normal.clone(), this.uv.clone() );
    };
    ThreeBSP.Vertex.prototype.add = function( vertex ) {
      this.x += vertex.x;
      this.y += vertex.y;
      this.z += vertex.z;
      return this;
    };
    ThreeBSP.Vertex.prototype.subtract = function( vertex ) {
      this.x -= vertex.x;
      this.y -= vertex.y;
      this.z -= vertex.z;
      return this;
    };
    ThreeBSP.Vertex.prototype.multiplyScalar = function( scalar ) {
      this.x *= scalar;
      this.y *= scalar;
      this.z *= scalar;
      return this;
    };
    ThreeBSP.Vertex.prototype.cross = function( vertex ) {
      var x = this.x,
        y = this.y,
        z = this.z;

      this.x = y * vertex.z - z * vertex.y;
      this.y = z * vertex.x - x * vertex.z;
      this.z = x * vertex.y - y * vertex.x;
      
      return this;
    };
    ThreeBSP.Vertex.prototype.normalize = function() {
      var length = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
      
      this.x /= length;
      this.y /= length;
      this.z /= length;
      
      return this;
    };
    ThreeBSP.Vertex.prototype.dot = function( vertex ) {
      return this.x * vertex.x + this.y * vertex.y + this.z * vertex.z;
    };
    ThreeBSP.Vertex.prototype.lerp = function( a, t ) {
      this.add(
        a.clone().subtract( this ).multiplyScalar( t )
      );
      
      this.normal.add(
        a.normal.clone().sub( this.normal ).multiplyScalar( t )
      );
      
      this.uv.add(
        a.uv.clone().sub( this.uv ).multiplyScalar( t )
      );
      
      return this;
    };
    ThreeBSP.Vertex.prototype.interpolate = function( other, t ) {
      return this.clone().lerp( other, t );
    };
    ThreeBSP.Vertex.prototype.applyMatrix4 = function ( m ) {

      // input: THREE.Matrix4 affine matrix

      var x = this.x, y = this.y, z = this.z;

      var e = m.elements;

      this.x = e[0] * x + e[4] * y + e[8]  * z + e[12];
      this.y = e[1] * x + e[5] * y + e[9]  * z + e[13];
      this.z = e[2] * x + e[6] * y + e[10] * z + e[14];

      return this;

    }
    
    
    ThreeBSP.Node = function( polygons ) {
      var i, polygon_count,
        front = [],
        back = [];

      this.polygons = [];
      this.front = this.back = undefined;
      
      if ( !(polygons instanceof Array) || polygons.length === 0 ) return;

      this.divider = polygons[0].clone();
      
      for ( i = 0, polygon_count = polygons.length; i < polygon_count; i++ ) {
        this.divider.splitPolygon( polygons[i], this.polygons, this.polygons, front, back );
      }   
      
      if ( front.length > 0 ) {
        this.front = new ThreeBSP.Node( front );
      }
      
      if ( back.length > 0 ) {
        this.back = new ThreeBSP.Node( back );
      }
    };
    ThreeBSP.Node.isConvex = function( polygons ) {
      var i, j;
      for ( i = 0; i < polygons.length; i++ ) {
        for ( j = 0; j < polygons.length; j++ ) {
          if ( i !== j && polygons[i].classifySide( polygons[j] ) !== BACK ) {
            return false;
          }
        }
      }
      return true;
    };
    ThreeBSP.Node.prototype.build = function( polygons ) {
      var i, polygon_count,
        front = [],
        back = [];
      
      if ( !this.divider ) {
        this.divider = polygons[0].clone();
      }

      for ( i = 0, polygon_count = polygons.length; i < polygon_count; i++ ) {
        this.divider.splitPolygon( polygons[i], this.polygons, this.polygons, front, back );
      }   
      
      if ( front.length > 0 ) {
        if ( !this.front ) this.front = new ThreeBSP.Node();
        this.front.build( front );
      }
      
      if ( back.length > 0 ) {
        if ( !this.back ) this.back = new ThreeBSP.Node();
        this.back.build( back );
      }
    };
    ThreeBSP.Node.prototype.allPolygons = function() {
      var polygons = this.polygons.slice();
      if ( this.front ) polygons = polygons.concat( this.front.allPolygons() );
      if ( this.back ) polygons = polygons.concat( this.back.allPolygons() );
      return polygons;
    };
    ThreeBSP.Node.prototype.clone = function() {
      var node = new ThreeBSP.Node();
      
      node.divider = this.divider.clone();
      node.polygons = this.polygons.map( function( polygon ) { return polygon.clone(); } );
      node.front = this.front && this.front.clone();
      node.back = this.back && this.back.clone();
      
      return node;
    };
    ThreeBSP.Node.prototype.invert = function() {
      var i, polygon_count, temp;
      
      for ( i = 0, polygon_count = this.polygons.length; i < polygon_count; i++ ) {
        this.polygons[i].flip();
      }
      
      this.divider.flip();
      if ( this.front ) this.front.invert();
      if ( this.back ) this.back.invert();
      
      temp = this.front;
      this.front = this.back;
      this.back = temp;
      
      return this;
    };
    ThreeBSP.Node.prototype.clipPolygons = function( polygons ) {
      var i, polygon_count,
        front, back;

      if ( !this.divider ) return polygons.slice();
      
      front = [], back = [];
      
      for ( i = 0, polygon_count = polygons.length; i < polygon_count; i++ ) {
        this.divider.splitPolygon( polygons[i], front, back, front, back );
      }

      if ( this.front ) front = this.front.clipPolygons( front );
      if ( this.back ) back = this.back.clipPolygons( back );
      else back = [];

      return front.concat( back );
    };
    
    ThreeBSP.Node.prototype.clipTo = function( node ) {
      this.polygons = node.clipPolygons( this.polygons );
      if ( this.front ) this.front.clipTo( node );
      if ( this.back ) this.back.clipTo( node );
    };
    return ThreeBSP;
  }

全部完整代码可以移步 【Threejs效果:挖空几何体】ThreeBSP实现墙体挖洞

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Threejs效果:挖空几何体】ThreeBSP实现墙体挖洞 的相关文章

随机推荐

  • SpringBoot 集成积木报表

    前言 积木报表是jeecg的一款开源但代码不开源的一款自定义报表 可以基于 网页灵活调整报表的布局 样式等内容 无需编程 专为企业数据分析 报表制作而设计 降低管理人员汇总制作报表的门槛 解决各类日常管理和 汇报的难题 但是因为代码不开源所
  • SQL 入门的必读好书

    点击蓝色 有关SQL 关注我哟 加个 星标 天天与10000人一起快乐成长 最近 很多朋友来问我 有没有入门 SQL 的好书 与这些朋友聊天发现 大部分人都没有系统学过计算机专业的专修课 有从物流转行的 有从会计专业扩展的 还有从运维行业转
  • 出现“java.sql.SQLException: 无法转换为内部表示”解决方法

    现在 java sql SQLException 无法转换为内部表示 很可能是因为数据库某字段的类型出错了 比如程序将某字段当做Integer类型 而数据库存储又使用另外一种类型 不如String 建议出现这样问题的同行们认真检查一下代码
  • 软件配置管理

    第一章 1 软件配置管理用于控制变化 2 软件配置管理 Software Configuration Management SCM 是指一套管理软件开发和维护过程中所产生的各种中间软件产品的方法和规则 它是控制软件系统演变的学科 3 软件配
  • java8之lambda表达式

    java8 近期 在一个不完全的统计中 java8的普及率已经到达了近80 图 1 相比之前的java版本 下面两个是java8出现带来最大的影响 其一是极大地简化了代码的复杂度尤其是在处理集合以及接口这两个方面 除此之外 java8引入了
  • Linux系统FTP传输协议

    目录 一 FTP传输协议 什么是FTP传输协议 FTP数据连接的两种方式 二 如何使用FTP传输协议 三 设置黑白名单 设置黑名单 设置白名单 一 FTP传输协议 什么是FTP传输协议 FTP协议 文件传输协议 网络上控制文件传输的双向性
  • 中国央行数字货币或比Libra更早发行,考虑让非政府机构参与试点

    中国官员和专家们表示 中国正在测试推出中国首款央行数字货币 CBDC 的多种方式 他们预计私营机构将更多地参与创造政府支持的货币 基于一些领域正在进行的试验 引入 CBDC 的时机已经接近成熟 但与中国央行关系密切的专家们周一表示 Face
  • 区块链教育应用案例_区块链技术在教育领域中的应用研究

    来源 廊坊云报 廊坊日报讯教育对一个国家来说意味着希望 教育行业数字的应用是各行各业发展的基础 只有通过完善的教育体系 才能培育出更加优秀的人才来输送到各个行业 所以说教育领域是一个重要领域 其他重要领域的未来 包括科学 医学 农业 工业和
  • 华为hilens 系统制作

    恢复出厂设置 https support huawei com enterprise zh doc EDOC1100112066 9b0a1fba 长按RST按钮2 3秒 在这个过程中 短按电源按钮后松开 当前面板健康指示灯出现橙色 常亮
  • Debian 12 发布,迄今为止最佳 Linux 版本

    Debian 项目今天发布了 Debian 12 Bookworm 操作系统的最终版本 这是一个重大发布 带来了几个新功能 更新的组件和许多改进 凭借其长期稳定和安全的历史 Debian 12 备受全球开源爱好者的热切期待 这个新版本带来了
  • 图书馆管理系统开发(C# && Sql Server)

    图书馆管理系统 C S架构软件 开发 主要步骤 遇见问题 1 主要步骤 1 1 学习主干知识 大概懂得数据库相关sql语法 大概懂得C 语法 C 菜鸟教程 把基础篇看看 大概掌握 Net开发窗口界面 Net教程 然后可以实战一下项目 VS2
  • 将嘉立创中元件导出为AD封装库使用

    AD封装库的选择和元件的查找实在让人头大 我们不妨使用好嘉立创提供的丰富元器件库 如果想要找到想要的元件 可以直接去嘉立创EDA 标准版 的元件库中寻找 在符号类型中可以找到原理图文件 很奇怪 在嘉立创商城中直接搜索的话元器件会比在嘉立创E
  • python列表输出去掉引号_如何从导出的python列表中删除逗号、引号和圆括号?

    你们帮了我最后一个新手的忙 所以我想我会再问一次 现在 我的Python 3代码从CSV文件中获取数据 将数据存储为列表 创建该数据的排列 并以列格式将其导出回新的CSV文件 不幸的是 导出列表的格式不适合我的需要 我的问题是 如何在pyt
  • vue3.0项目报错:删除node包重新装报错

    前言 vue3 0的项目删除node包以后重新装项目 会报错 vue loader v16 找不到 安装以后下次再删包 再装会报错webpack的问题 解决办法 在新建项目后 打开pack json文件 找到 devDependencies
  • 【积累】Element-ui,el-dialog里面嵌入el-form,resetFields失效问题

    记一次element ui el dialog里面嵌入el form 使用resetFields方法初始化表单失效 问题记录 前提 当el form在一个el dialog中 dialog显示与否绑定变量 showDialog ref 为
  • 用DC-DC 升压降压以及产生负电压的原理及应用

    文章目录 前言 一 Boost和Buck电路 二 实际使用 1 DC DC芯片 2 DC DC芯片产生负电压 前言 在设计电源电路时经常会用到升压降压和负电压等电路 博主结合理论知识和实际应用加上自己理解 分享这篇文章 一 Boost和Bu
  • 设置无线路由器与有线网络在同一网段

    公司有两台路由器 一台连接internet的大路由器 一台无线路由器 两台路由器不在同一网段 所以无法实现互联互通 在一个局域网中很不方便 原设置 无线路由器的WAN口连接到大路由器上 插网线 无线路由器的WAN IP设置与大路由器一个网段
  • 【微信小程序】wx.request出现undefined

    偶现 天啦噜 一直困惑了很久的bug终于找到原因了 示例代码如下 wx request sucess function res if res statusCode 200 res data status 200 do something e
  • csdn中使用KaTeX给公式编号

    说明 csdn用的公式编辑器是Katex 并不是LaTeX 两者语法有些区别 比如LaTeX中的公式编号 begin equation 在KateX中就会解析错误 katex中 给公式编号用 tag 1 的形式 例如 E mc 2 tag
  • 【Threejs效果:挖空几何体】ThreeBSP实现墙体挖洞

    1 效果如下 2 代码如下 基本思路 1 创建两个mesh 一个墙体 一个窗户 2 然后取墙体和窗户的差集 将差集转换成几何体 3 根据几何体新建mesh 并贴纹理 依赖库有三个 import as THREE from three imp