p5打造一个三维山脉地形图效果代码

代码语言:html

所属分类:三维

代码描述:p5打造一个三维山脉地形图效果代码

代码标签: 三维 山脉 地形图 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">
  

  
  
  
<style>
* { margin:0; padding:0; } 
html, body { width:100%; height:100%; overflow: hidden; background:black;} 
canvas { display:block; }
#controls {
  z-index: 2;
  margin: 20px;
  position: absolute;
  top: 0; left: 0;
  color: white;
}
</style>



</head>

<body translate="no" >
  <div id="controls"></div>
 
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/p5.0.10.2.js"></script>
  
      <script>
class Vec3{
  constructor(x, y, z, r=10){
    this.x = x;
    this.y = y;
    this.z = z;
    this.r = r;
  }
  op(p, f){
    this.x = f(this.x, p.x != undefined ? p.x : p);
    this.y = f(this.y, p.y != undefined ? p.y : p);
    this.z = f(this.z, p.z != undefined ? p.z : p);
    return this;
  }
  normalize(){
    let d = sqrt(this.x*this.x + this.y*this.y + this.z*this.z);
    return this.div(d);
  }
  dot   (p){return this.x*p.x + this.y*p.y + this.z*p.z}
  plus  (p){return this.op(p, (a, b) => a + b)}
  minus (p){return this.op(p, (a, b) => a - b)}
  times (p){return this.op(p, (a, b) => a * b)}
  div   (p){return this.op(p, (a, b) => a / b)}
  distTo(p){return Math.hypot(this.x-p.x, this.y-p.y, this.x-p.z)}
  clone  (){return new Vec3(this.x, this.y, this.z, this.r)}
  updateRotation(){
    let {x, y, z} = this.clone().minus(origin);
    this.screenCoord = [
      (x*cx - y*sx),
      (y*cx + x*sx)*cy + sy*z
    ];
    this.depth = z*cy - sy*(y*cx + x*sx);
  }
  render(fc=.5, sc = 1){
    fill(fc);
    stroke(sc);
    strokeWeight(1);
    ellipse(...this.screenCoord, this.r);
  }
}

class Shape{
  constructor(points, {strokeColor="white", fillColor=color(1, .5), strokeWeight=1, showPoints = true,}){
    this.points = points;
    this.center = new Vec3(0, 0, 0);
    this.strokeColor = strokeColor;
    this.fillColor = fillColor;
    this.strokeWeight = strokeWeight;
    this.showPoints = showPoints;
    for (let p of this.points) this.center.plus(p);
    this.center.div(this.points.length);
    
    this.computeNormal();
  }
  computeNormal(){
    if (this.points.length > 2){
      let A = this.points[1].clone().minus(this.points[0]);
      let B = this.points[2].clone().minus(this.points[0]);
      this.normal = (new Vec3(
        A.y*B.z-A.z*B.y,
        A.z*B.x-A.x*B.z,
        A.x*B.y-A.y*B.x,
      )).normalize();
    }    
  }
  updateRotation(){
    this.points.map(p => p.updateRotation());
    this.center.updateRotation();
    this.depth = this.center.depth;
  }
  render(){
    strokeWeight(this.strokeWeight);
    stroke(this.strokeColor);
    fill(this.fillColor);
    beginShape();
    for (let p of this.points) vertex(...(p.screenCoord));
    endShape(CLOSE);
    if (this.showPoints){
      let points = [...(this.points), this.center].sort((a, b) => a.depth-b.depth);
      for (let p of points) p.render();
    }
  }
}

class Geom{
  constructor(verts, faces, style = {}){
    this.shapes = [];
    for (let face of faces){
      let shape = new Shape(face.map(idx => verts[idx]), style);
      this.shapes.push(shape);
    }
  }
  updateRotation(){
    this.shapes.map(s => s.updateRotation());
  }
  render(){
    let shapes = this.shapes.sort((a, b) => a.depth - b.depth);
    for (let s of shapes) s.render();
  }
}

let Box = (anchor, w, l, h, style={}) => {
  let verts = [
    anchor,
    anchor.clone().plus(new Vec3(w, 0, 0)),
  ];
  verts = verts.concat(verts.map(p => p.clone().plus(new Vec3(0, l, 0))));
  verts = verts.concat(verts.map(p => p.clone().plus(new Vec3(0, 0, h))));
  let faces = [
    [0, 1, 3, 2], //bottom
    [4, 5, 7, 6], //top
    [0, 1, 5, 4], //+x
    [3, 2, 6, 7], //-x
    [1, 3, 7, 5], //+y
    [2, 0, 4, 6], //-y
  ];
  return new Geom(verts, faces, style);
}

let Tree = (x, y, z, h) => {
  z += 5;
 .........完整代码请登录后点击上方下载按钮下载查看

网友评论0