boxmoe_header_banner_img

Hello! 欢迎来到我的博客!

加载中

文章导读

图形学 – Canvas2D实现3D渲染


avatar
xiaoifei 2026年9月12日 9

step1:实现屏幕坐标与NDC坐标换算

需要实现透视投影,需要通过/z公式,而这个公式需要在NDC空间中
通过创建[-1~1]之间的x,y点,将其映射到canvas的width和height上

由于canvas画布的渲染是以左上角顶点为原点,与NDC坐标以中心点为原点不同,因此需要进行toScreen转换
由于canvasy向下为正,所以需要用1-归一化结果,将其变成向上为正
这点与图形学中的视口变换内容是相同的

"use strict"
let ctx = game.getContext("2d");
game.width = 800
game.height = 800 

const BACKGROUND = "#292929"
const FOREGROUND = "#5e5e5e"

function clear() {
  ctx.fillStyle = BACKGROUND;
  ctx.fillRect(0, 0, game.width, game.height);
}
clear()

function point({x,y}) {
  const s = 50
  ctx.fillStyle = FOREGROUND;
  ctx.fillRect(x - s/2, y - s/2, s, s);
}

/**
 * Canonical Cube to Screen
 */
function toScreen(p) {
  return {
    x: (p.x + 1) / 2 * game.width,
    y: (1 - (p.y + 1) / 2) * game.height // 变为以y向上为正
  }
}

point(toScreen({x:0,y:0}))
point(toScreen({x:0.5,y:0.5}))

随后我们编写投影函数

function project({x,y,z}) {
  return {
    x: x / z,
    y: y / z,
  }
}

point(toScreen(project({x:0.5,y:0.5,z:2})))
point(toScreen(project({x:0.5,y:0.5,z:1})))

可以看到,同一个点,距离我们的z不同,屏幕上显示的坐标也不同,符合近大远小的效果

step2:为立方体添加动画

浏览器提供了内置的API:rAF(requestAnimationFrame),浏览器每帧默认按照屏幕刷新率渲染,都会调用一次传入的回调函数

let lastTime = performance.now();
function update(now) {
	const dt = (now - lastTime) / 1000 // 帧间隔时间
	lastTime = now
    // 更新游戏状态
    // 绘制 Canvas

    requestAnimationFrame(update)
}
requestAnimationFrame(update)

回调函数参数可以拿到当前时间戳,由此计算出帧间隔时间
而物体位移由deltaTime计算出的话,就不会受到刷新率的影响

60 FPS:每帧走得时间少,但帧多;30 FPS:每帧走得时间多,但帧少。
但是最终1秒都只会移动100px

我们可以将点抽成一个单独的对象数组

const vertexs = [
  { x: 0.25, y: 0.25, z: 0.25 },
  { x: 0.25, y: -0.25, z: 0.25 }, 
  { x: -0.25, y: 0.25, z: 0.25 },
  { x: -0.25, y: -0.25, z: 0.25 },

  { x: 0.25, y: 0.25, z: -0.25 },
  { x: 0.25, y: -0.25, z: -0.25 },
  { x: -0.25, y: 0.25, z: -0.25 },
  { x: -0.25, y: -0.25, z: -0.25 }
]

此时原点为我们的眼睛,我们处于立方体的中心位置
我们可以逐渐增加这些立方体顶点的Z值,让他向前移动

function translate_z({x, y, z}, dz) {
  return {x, y, z: z + dz};
}
let dz = 0;
let lastTime = performance.now();

function update(now) {
  const dt = (now - lastTime) / 1000
  lastTime = now
  clear()

  dz += dt * 1
  for (let v of vertexs) {
    let tv = translate_z(v, dz)
    let pv = project(tv)
    point(toScreen(pv));
  }

  requestAnimationFrame(update) // 预约下一帧渲染
}
requestAnimationFrame(update)

我们使用for循环,在每帧绘制出所有的顶点,并进行位移,投影,渲染的操作

可以为立方体添加旋转效果

function rotate_y({x,y,z},angle) {
  const s = Math.sin(angle)
  const c = Math.cos(angle)
  return {
    x: x*c+z*s,
    y,
    z: -x*s+z*c,
  }
}

function update(now) {
  const dt = (now - lastTime) / 1000
  lastTime = now
  clear()

  dz += dt * 1
  dangle += Math.PI * dt
  for (let v of vertexs) {
    let rv = rotate_y(v,dangle)
    let tv = translate_z(rv, dz)
    let pv = project(tv)
    point(toScreen(pv));
  }

  requestAnimationFrame(update)
}

step3:闭合顶点线段

目前顶点还没有连成线组成一个平面,所以我们通过lineTo来连接这些顶点

function line(p1, p2) {
  ctx.strokeStyle = FOREGROUND
  ctx.lineWidth = 1
  ctx.beginPath()
  ctx.moveTo(p1.x, p1.y)
  ctx.lineTo(p2.x, p2.y)
  ctx.stroke()
}

我们需要两个顶点确定一个线段,这里我们用数组来装vertexs的索引。

const vertexs = [
  { x: 0.25, y: 0.25, z: 0.25 },
  { x: 0.25, y: -0.25, z: 0.25 },
  { x: -0.25, y: -0.25, z: 0.25 },
  { x: -0.25, y: 0.25, z: 0.25 },


  { x: 0.25, y: 0.25, z: -0.25 },
  { x: 0.25, y: -0.25, z: -0.25 },
  { x: -0.25, y: -0.25, z: -0.25 },
  { x: -0.25, y: 0.25, z: -0.25 },
]

const faces = [
  [ 0,1,2,3 ], // 组成一个面需要的顶点(用索引记录)
  [ 4,5,6,7 ],
  [ 0,4 ],
  [ 1,5 ],
  [ 2,6 ],
  [ 3,7 ],
]

一个面由闭合线段组成,所以我们需要取出faces的一个数组,并遍历数组的元素得到vertex,并将其渲染之后使用line连接

function update(now) {
	// 顶点渲染
	// ...
	// 边渲染
	for (let f of faces) {
	    for(let i = 0; i < f.length;i++){
	      const sourceVertex = vertexs[f[i]]
	      const targetVertex = vertexs[f[(i + 1) % f.length]]
	  
	      const source = toScreen(
	        project(
	          translate_z(
	            rotate_y(sourceVertex, dangle),
	            dz
	          )
	        )
	      )
	  
	      const target = toScreen(
	        project(
	          translate_z(
	            rotate_y(targetVertex, dangle),
	            dz
	          )
	        )
	      )
	  
	      line(source, target)
	    }
    }
}

step4:完整实现

"use strict"
let ctx = game.getContext("2d");
game.width = 400
game.height = 400

const BACKGROUND = "#292929"
const FOREGROUND = "#8cff5a"

function clear() {
  ctx.fillStyle = BACKGROUND;
  ctx.fillRect(0, 0, game.width, game.height);
}

function point({ x, y }) {
  const s = 5
  ctx.fillStyle = FOREGROUND;
  ctx.fillRect(x - s / 2, y - s / 2, s, s);
}

/**
 * Canonical Cube to Screen
 */
function toScreen(p) {
  return {
    x: (p.x + 1) / 2 * game.width,
    y: (1 - (p.y + 1) / 2) * game.height // 变为以y向上为正
  }
}

function project({ x, y, z }) {
  return {
    x: x / z,
    y: y / z,
  }
}

function line(p1, p2) {
  ctx.strokeStyle = FOREGROUND
  ctx.lineWidth = 1
  ctx.beginPath()
  ctx.moveTo(p1.x, p1.y)
  ctx.lineTo(p2.x, p2.y)
  ctx.stroke()
}

let dz = 1;
let dangle = 0;
let lastTime = performance.now();

const vertexs = [
  { x: 0.25, y: 0.25, z: 0.25 },
  { x: 0.25, y: -0.25, z: 0.25 },
  { x: -0.25, y: -0.25, z: 0.25 },
  { x: -0.25, y: 0.25, z: 0.25 },


  { x: 0.25, y: 0.25, z: -0.25 },
  { x: 0.25, y: -0.25, z: -0.25 },
  { x: -0.25, y: -0.25, z: -0.25 },
  { x: -0.25, y: 0.25, z: -0.25 },
]

const faces = [
  [ 0,1,2,3 ],
  [ 4,5,6,7 ],
  [ 0,4 ],
  [ 1,5 ],
  [ 2,6 ],
  [ 3,7 ],
]


function translate_z({ x, y, z }, dz) {
  return { x, y, z: z + dz };
}

function rotate_y({ x, y, z }, angle) {
  const s = Math.sin(angle)
  const c = Math.cos(angle)
  return {
    x: x * c + z * s,
    y,
    z: -x * s + z * c,
  }
}

function update(now) {
  const dt = (now - lastTime) / 1000
  lastTime = now
  clear()

  // dz += dt * 1
  dangle += Math.PI * dt
  for (let v of vertexs) {
    let rv = rotate_y(v, dangle)
    let tv = translate_z(rv, dz)
    let pv = project(tv)
    point(toScreen(pv));
  }
  for (let f of faces) {
    for(let i = 0; i < f.length;i++){
      const sourceVertex = vertexs[f[i]]
      const targetVertex = vertexs[f[(i + 1) % f.length]]
  
      const source = toScreen(
        project(
          translate_z(
            rotate_y(sourceVertex, dangle),
            dz
          )
        )
      )
  
      const target = toScreen(
        project(
          translate_z(
            rotate_y(targetVertex, dangle),
            dz
          )
        )
      )
  
      line(source, target)
    }
  }

  requestAnimationFrame(update)
}
requestAnimationFrame(update)

step5:制作一个Gopher模型

当中包含了vertexs顶点和faces面数据

export const vertexs=[{x:0.16,y:-0.46,z:0},{x:0.13856,y:-0.46,z:0.065},{x:0.08,y:-0.46,z:0.11258},{x:0,y:-0.46,z:0.13},{x:-0.08,y:-0.46,z:0.11258},{x:-0.13856,y:-0.46,z:0.065},{x:-0.16,y:-0.46,z:0},{x:-0.13856,y:-0.46,z:-0.065},{x:-0.08,y:-0.46,z:-0.11258},{x:0,y:-0.46,z:-0.13},{x:0.08,y:-0.46,z:-0.11258},{x:0.13856,y:-0.46,z:-0.065},{x:0.28,y:-0.42,z:0},{x:0.24249,y:-0.42,z:0.105},{x:0.14,y:-0.42,z:0.18187},{x:0,y:-0.42,z:0.21},{x:-0.14,y:-0.42,z:0.18187},{x:-0.24249,y:-0.42,z:0.105},{x:-0.28,y:-0.42,z:0},{x:-0.24249,y:-0.42,z:-0.105},{x:-0.14,y:-0.42,z:-0.18187},{x:0,y:-0.42,z:-0.21},{x:0.14,y:-0.42,z:-0.18187},{x:0.24249,y:-0.42,z:-0.105},{x:0.32,y:-0.32,z:0},{x:0.27713,y:-0.32,z:0.1175},{x:0.16,y:-0.32,z:0.20352},{x:0,y:-0.32,z:0.235},{x:-0.16,y:-0.32,z:0.20352},{x:-0.27713,y:-0.32,z:0.1175},{x:-0.32,y:-0.32,z:0},{x:-0.27713,y:-0.32,z:-0.1175},{x:-0.16,y:-0.32,z:-0.20352},{x:0,y:-0.32,z:-0.235},{x:0.16,y:-0.32,z:-0.20352},{x:0.27713,y:-0.32,z:-0.1175},{x:0.315,y:-0.12,z:0},{x:0.2728,y:-0.12,z:0.1175},{x:0.1575,y:-0.12,z:0.20352},{x:0,y:-0.12,z:0.235},{x:-0.1575,y:-0.12,z:0.20352},{x:-0.2728,y:-0.12,z:0.1175},{x:-0.315,y:-0.12,z:0},{x:-0.2728,y:-0.12,z:-0.1175},{x:-0.1575,y:-0.12,z:-0.20352},{x:0,y:-0.12,z:-0.235},{x:0.1575,y:-0.12,z:-0.20352},{x:0.2728,y:-0.12,z:-0.1175},{x:0.32,y:0.1,z:0},{x:0.27713,y:0.1,z:0.12},{x:0.16,y:0.1,z:0.20785},{x:0,y:0.1,z:0.24},{x:-0.16,y:0.1,z:0.20785},{x:-0.27713,y:0.1,z:0.12},{x:-0.32,y:0.1,z:0},{x:-0.27713,y:0.1,z:-0.12},{x:-0.16,y:0.1,z:-0.20785},{x:0,y:0.1,z:-0.24},{x:0.16,y:0.1,z:-0.20785},{x:0.27713,y:0.1,z:-0.12},{x:0.325,y:0.3,z:0},{x:0.28146,y:0.3,z:0.1175},{x:0.1625,y:0.3,z:0.20352},{x:0,y:0.3,z:0.235},{x:-0.1625,y:0.3,z:0.20352},{x:-0.28146,y:0.3,z:0.1175},{x:-0.325,y:0.3,z:0},{x:-0.28146,y:0.3,z:-0.1175},{x:-0.1625,y:0.3,z:-0.20352},{x:0,y:0.3,z:-0.235},{x:0.1625,y:0.3,z:-0.20352},{x:0.28146,y:0.3,z:-0.1175},{x:0.27,y:0.43,z:0},{x:0.23383,y:0.43,z:0.1},{x:0.135,y:0.43,z:0.17321},{x:0,y:0.43,z:0.2},{x:-0.135,y:0.43,z:0.17321},{x:-0.23383,y:0.43,z:0.1},{x:-0.27,y:0.43,z:0},{x:-0.23383,y:0.43,z:-0.1},{x:-0.135,y:0.43,z:-0.17321},{x:0,y:0.43,z:-0.2},{x:0.135,y:0.43,z:-0.17321},{x:0.23383,y:0.43,z:-0.1},{x:0.17,y:0.51,z:0},{x:0.14722,y:0.51,z:0.065},{x:0.085,y:0.51,z:0.11258},{x:0,y:0.51,z:0.13},{x:-0.085,y:0.51,z:0.11258},{x:-0.14722,y:0.51,z:0.065},{x:-0.17,y:0.51,z:0},{x:-0.14722,y:0.51,z:-0.065},{x:-0.085,y:0.51,z:-0.11258},{x:0,y:0.51,z:-0.13},{x:0.085,y:0.51,z:-0.11258},{x:0.14722,y:0.51,z:-0.065},{x:0.055,y:0.545,z:0},{x:0.04763,y:0.545,z:0.0225},{x:0.0275,y:0.545,z:0.03897},{x:0,y:0.545,z:0.045},{x:-0.0275,y:0.545,z:0.03897},{x:-0.04763,y:0.545,z:0.0225},{x:-0.055,y:0.545,z:0},{x:-0.04763,y:0.545,z:-0.0225},{x:-0.0275,y:0.545,z:-0.03897},{x:0,y:0.545,z:-0.045},{x:0.0275,y:0.545,z:-0.03897},{x:0.04763,y:0.545,z:-0.0225},{x:-0.238,y:0.405,z:0.025},{x:-0.24984,y:0.4485,z:0.025},{x:-0.28084,y:0.47538,z:0.025},{x:-0.31916,y:0.47538,z:0.025},{x:-0.35016,y:0.4485,z:0.025},{x:-0.362,y:0.405,z:0.025},{x:-0.35016,y:0.3615,z:0.025},{x:-0.31916,y:0.33462,z:0.025},{x:-0.28084,y:0.33462,z:0.025},{x:-0.24984,y:0.3615,z:0.025},{x:-0.238,y:0.405,z:-0.075},{x:-0.24984,y:0.4485,z:-0.075},{x:-0.28084,y:0.47538,z:-0.075},{x:-0.31916,y:0.47538,z:-0.075},{x:-0.35016,y:0.4485,z:-0.075},{x:-0.362,y:0.405,z:-0.075},{x:-0.35016,y:0.3615,z:-0.075},{x:-0.31916,y:0.33462,z:-0.075},{x:-0.28084,y:0.33462,z:-0.075},{x:-0.24984,y:0.3615,z:-0.075},{x:-0.264,y:0.405,z:-0.088},{x:-0.27454,y:0.43682,z:-0.088},{x:-0.3,y:0.45,z:-0.088},{x:-0.32546,y:0.43682,z:-0.088},{x:-0.336,y:0.405,z:-0.088},{x:-0.32546,y:0.37318,z:-0.088},{x:-0.3,y:0.36,z:-0.088},{x:-0.27454,y:0.37318,z:-0.088},{x:-0.034,y:0.255,z:-0.215},{x:-0.0478,y:0.313,z:-0.215},{x:-0.0855,y:0.35546,z:-0.215},{x:-0.137,y:0.371,z:-0.215},{x:-0.1885,y:0.35546,z:-0.215},{x:-0.2262,y:0.313,z:-0.215},{x:-0.24,y:0.255,z:-0.215},{x:-0.2262,y:0.197,z:-0.215},{x:-0.1885,y:0.15454,z:-0.215},{x:-0.137,y:0.139,z:-0.215},{x:-0.0855,y:0.15454,z:-0.215},{x:-0.0478,y:0.197,z:-0.215},{x:-0.041,y:0.255,z:-0.295},{x:-0.05386,y:0.3085,z:-0.295},{x:-0.089,y:0.34766,z:-0.295},{x:-0.137,y:0.362,z:-0.295},{x:-0.185,y:0.34766,z:-0.295},{x:-0.22014,y:0.3085,z:-0.295},{x:-0.233,y:0.255,z:-0.295},{x:-0.22014,y:0.2015,z:-0.295},{x:-0.185,y:0.16234,z:-0.295},{x:-0.137,y:0.148,z:-0.295},{x:-0.089,y:0.16234,z:-0.295},{x:-0.05386,y:0.2015,z:-0.295},{x:-0.121,y:0.276,z:-0.321},{x:-0.12826,y:0.30421,z:-0.321},{x:-0.14726,y:0.32165,z:-0.321},{x:-0.17074,y:0.32165,z:-0.321},{x:-0.18974,y:0.30421,z:-0.321},{x:-0.197,y:0.276,z:-0.321},{x:-0.18974,y:0.24779,z:-0.321},{x:-0.17074,y:0.23035,z:-0.321},{x:-0.14726,y:0.23035,z:-0.321},{x:-0.12826,y:0.24779,z:-0.321},{x:-0.301,y:-0.145,z:0.02},{x:-0.30862,y:-0.0955,z:0.02},{x:-0.327,y:-0.075,z:0.02},{x:-0.34538,y:-0.0955,z:0.02},{x:-0.353,y:-0.145,z:0.02},{x:-0.34538,y:-0.1945,z:0.02},{x:-0.327,y:-0.215,z:0.02},{x:-0.30862,y:-0.1945,z:0.02},{x:-0.301,y:-0.145,z:-0.085},{x:-0.30862,y:-0.0955,z:-0.085},{x:-0.327,y:-0.075,z:-0.085},{x:-0.34538,y:-0.0955,z:-0.085},{x:-0.353,y:-0.145,z:-0.085},{x:-0.34538,y:-0.1945,z:-0.085},{x:-0.327,y:-0.215,z:-0.085},{x:-0.30862,y:-0.1945,z:-0.085},{x:-0.154,y:-0.466,z:-0.075},{x:-0.1748,y:-0.466,z:0.01127},{x:-0.225,y:-0.466,z:0.047},{x:-0.2752,y:-0.466,z:0.01127},{x:-0.296,y:-0.466,z:-0.075},{x:-0.2752,y:-0.466,z:-0.16127},{x:-0.225,y:-0.466,z:-0.197},{x:-0.1748,y:-0.466,z:-0.16127},{x:-0.154,y:-0.495,z:-0.075},{x:-0.1748,y:-0.495,z:0.01127},{x:-0.225,y:-0.495,z:0.047},{x:-0.2752,y:-0.495,z:0.01127},{x:-0.296,y:-0.495,z:-0.075},{x:-0.2752,y:-0.495,z:-0.16127},{x:-0.225,y:-0.495,z:-0.197},{x:-0.1748,y:-0.495,z:-0.16127},{x:0.362,y:0.405,z:0.025},{x:0.35016,y:0.4485,z:0.025},{x:0.31916,y:0.47538,z:0.025},{x:0.28084,y:0.47538,z:0.025},{x:0.24984,y:0.4485,z:0.025},{x:0.238,y:0.405,z:0.025},{x:0.24984,y:0.3615,z:0.025},{x:0.28084,y:0.33462,z:0.025},{x:0.31916,y:0.33462,z:0.025},{x:0.35016,y:0.3615,z:0.025},{x:0.362,y:0.405,z:-0.075},{x:0.35016,y:0.4485,z:-0.075},{x:0.31916,y:0.47538,z:-0.075},{x:0.28084,y:0.47538,z:-0.075},{x:0.24984,y:0.4485,z:-0.075},{x:0.238,y:0.405,z:-0.075},{x:0.24984,y:0.3615,z:-0.075},{x:0.28084,y:0.33462,z:-0.075},{x:0.31916,y:0.33462,z:-0.075},{x:0.35016,y:0.3615,z:-0.075},{x:0.336,y:0.405,z:-0.088},{x:0.32546,y:0.43682,z:-0.088},{x:0.3,y:0.45,z:-0.088},{x:0.27454,y:0.43682,z:-0.088},{x:0.264,y:0.405,z:-0.088},{x:0.27454,y:0.37318,z:-0.088},{x:0.3,y:0.36,z:-0.088},{x:0.32546,y:0.37318,z:-0.088},{x:0.24,y:0.255,z:-0.215},{x:0.2262,y:0.313,z:-0.215},{x:0.1885,y:0.35546,z:-0.215},{x:0.137,y:0.371,z:-0.215},{x:0.0855,y:0.35546,z:-0.215},{x:0.0478,y:0.313,z:-0.215},{x:0.034,y:0.255,z:-0.215},{x:0.0478,y:0.197,z:-0.215},{x:0.0855,y:0.15454,z:-0.215},{x:0.137,y:0.139,z:-0.215},{x:0.1885,y:0.15454,z:-0.215},{x:0.2262,y:0.197,z:-0.215},{x:0.233,y:0.255,z:-0.295},{x:0.22014,y:0.3085,z:-0.295},{x:0.185,y:0.34766,z:-0.295},{x:0.137,y:0.362,z:-0.295},{x:0.089,y:0.34766,z:-0.295},{x:0.05386,y:0.3085,z:-0.295},{x:0.041,y:0.255,z:-0.295},{x:0.05386,y:0.2015,z:-0.295},{x:0.089,y:0.16234,z:-0.295},{x:0.137,y:0.148,z:-0.295},{x:0.185,y:0.16234,z:-0.295},{x:0.22014,y:0.2015,z:-0.295},{x:0.197,y:0.276,z:-0.321},{x:0.18974,y:0.30421,z:-0.321},{x:0.17074,y:0.32165,z:-0.321},{x:0.14726,y:0.32165,z:-0.321},{x:0.12826,y:0.30421,z:-0.321},{x:0.121,y:0.276,z:-0.321},{x:0.12826,y:0.24779,z:-0.321},{x:0.14726,y:0.23035,z:-0.321},{x:0.17074,y:0.23035,z:-0.321},{x:0.18974,y:0.24779,z:-0.321},{x:0.353,y:-0.145,z:0.02},{x:0.34538,y:-0.0955,z:0.02},{x:0.327,y:-0.075,z:0.02},{x:0.30862,y:-0.0955,z:0.02},{x:0.301,y:-0.145,z:0.02},{x:0.30862,y:-0.1945,z:0.02},{x:0.327,y:-0.215,z:0.02},{x:0.34538,y:-0.1945,z:0.02},{x:0.353,y:-0.145,z:-0.085},{x:0.34538,y:-0.0955,z:-0.085},{x:0.327,y:-0.075,z:-0.085},{x:0.30862,y:-0.0955,z:-0.085},{x:0.301,y:-0.145,z:-0.085},{x:0.30862,y:-0.1945,z:-0.085},{x:0.327,y:-0.215,z:-0.085},{x:0.34538,y:-0.1945,z:-0.085},{x:0.296,y:-0.466,z:-0.075},{x:0.2752,y:-0.466,z:0.01127},{x:0.225,y:-0.466,z:0.047},{x:0.1748,y:-0.466,z:0.01127},{x:0.154,y:-0.466,z:-0.075},{x:0.1748,y:-0.466,z:-0.16127},{x:0.225,y:-0.466,z:-0.197},{x:0.2752,y:-0.466,z:-0.16127},{x:0.296,y:-0.495,z:-0.075},{x:0.2752,y:-0.495,z:0.01127},{x:0.225,y:-0.495,z:0.047},{x:0.1748,y:-0.495,z:0.01127},{x:0.154,y:-0.495,z:-0.075},{x:0.1748,y:-0.495,z:-0.16127},{x:0.225,y:-0.495,z:-0.197},{x:0.2752,y:-0.495,z:-0.16127},{x:0.088,y:0.114,z:-0.24},{x:0.07621,y:0.1365,z:-0.24},{x:0.044,y:0.15297,z:-0.24},{x:0,y:0.159,z:-0.24},{x:-0.044,y:0.15297,z:-0.24},{x:-0.07621,y:0.1365,z:-0.24},{x:-0.088,y:0.114,z:-0.24},{x:-0.07621,y:0.0915,z:-0.24},{x:-0.044,y:0.07503,z:-0.24},{x:0,y:0.069,z:-0.24},{x:0.044,y:0.07503,z:-0.24},{x:0.07621,y:0.0915,z:-0.24},{x:0.082,y:0.114,z:-0.325},{x:0.07101,y:0.1335,z:-0.325},{x:0.041,y:0.14777,z:-0.325},{x:0,y:0.153,z:-0.325},{x:-0.041,y:0.14777,z:-0.325},{x:-0.07101,y:0.1335,z:-0.325},{x:-0.082,y:0.114,z:-0.325},{x:-0.07101,y:0.0945,z:-0.325},{x:-0.041,y:0.08023,z:-0.325},{x:0,y:0.075,z:-0.325},{x:0.041,y:0.08023,z:-0.325},{x:0.07101,y:0.0945,z:-0.325},{x:0.033,y:0.122,z:-0.341},{x:0.02333,y:0.13473,z:-0.341},{x:0,y:0.14,z:-0.341},{x:-0.02333,y:0.13473,z:-0.341},{x:-0.033,y:0.122,z:-0.341},{x:-0.02333,y:0.10927,z:-0.341},{x:0,y:0.104,z:-0.341},{x:0.02333,y:0.10927,z:-0.341},{x:-0.034,y:0.074,z:-0.292},{x:-0.002,y:0.074,z:-0.292},{x:-0.003,y:0.03,z:-0.297},{x:-0.01,y:0.019,z:-0.298},{x:-0.026,y:0.019,z:-0.298},{x:-0.033,y:0.03,z:-0.297},{x:0.002,y:0.074,z:-0.292},{x:0.034,y:0.074,z:-0.292},{x:0.033,y:0.03,z:-0.297},{x:0.026,y:0.019,z:-0.298},{x:0.01,y:0.019,z:-0.298},{x:0.003,y:0.03,z:-0.297},];export const faces=[[0,1],[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,9],[9,10],[10,11],[11,0],[12,13],[13,14],[14,15],[15,16],[16,17],[17,18],[18,19],[19,20],[20,21],[21,22],[22,23],[23,12],[0,12],[1,13],[2,14],[3,15],[4,16],[5,17],[6,18],[7,19],[8,20],[9,21],[10,22],[11,23],[24,25],[25,26],[26,27],[27,28],[28,29],[29,30],[30,31],[31,32],[32,33],[33,34],[34,35],[35,24],[12,24],[13,25],[14,26],[15,27],[16,28],[17,29],[18,30],[19,31],[20,32],[21,33],[22,34],[23,35],[36,37],[37,38],[38,39],[39,40],[40,41],[41,42],[42,43],[43,44],[44,45],[45,46],[46,47],[47,36],[24,36],[25,37],[26,38],[27,39],[28,40],[29,41],[30,42],[31,43],[32,44],[33,45],[34,46],[35,47],[48,49],[49,50],[50,51],[51,52],[52,53],[53,54],[54,55],[55,56],[56,57],[57,58],[58,59],[59,48],[36,48],[37,49],[38,50],[39,51],[40,52],[41,53],[42,54],[43,55],[44,56],[45,57],[46,58],[47,59],[60,61],[61,62],[62,63],[63,64],[64,65],[65,66],[66,67],[67,68],[68,69],[69,70],[70,71],[71,60],[48,60],[49,61],[50,62],[51,63],[52,64],[53,65],[54,66],[55,67],[56,68],[57,69],[58,70],[59,71],[72,73],[73,74],[74,75],[75,76],[76,77],[77,78],[78,79],[79,80],[80,81],[81,82],[82,83],[83,72],[60,72],[61,73],[62,74],[63,75],[64,76],[65,77],[66,78],[67,79],[68,80],[69,81],[70,82],[71,83],[84,85],[85,86],[86,87],[87,88],[88,89],[89,90],[90,91],[91,92],[92,93],[93,94],[94,95],[95,84],[72,84],[73,85],[74,86],[75,87],[76,88],[77,89],[78,90],[79,91],[80,92],[81,93],[82,94],[83,95],[96,97],[97,98],[98,99],[99,100],[100,101],[101,102],[102,103],[103,104],[104,105],[105,106],[106,107],[107,96],[84,96],[85,97],[86,98],[87,99],[88,100],[89,101],[90,102],[91,103],[92,104],[93,105],[94,106],[95,107],[108,109],[109,110],[110,111],[111,112],[112,113],[113,114],[114,115],[115,116],[116,117],[117,108],[118,119],[119,120],[120,121],[121,122],[122,123],[123,124],[124,125],[125,126],[126,127],[127,118],[108,118],[110,120],[112,122],[114,124],[116,126],[128,129],[129,130],[130,131],[131,132],[132,133],[133,134],[134,135],[135,128],[136,137],[137,138],[138,139],[139,140],[140,141],[141,142],[142,143],[143,144],[144,145],[145,146],[146,147],[147,136],[148,149],[149,150],[150,151],[151,152],[152,153],[153,154],[154,155],[155,156],[156,157],[157,158],[158,159],[159,148],[136,148],[139,151],[142,154],[145,157],[160,161],[161,162],[162,163],[163,164],[164,165],[165,166],[166,167],[167,168],[168,169],[169,160],[170,171],[171,172],[172,173],[173,174],[174,175],[175,176],[176,177],[177,170],[178,179],[179,180],[180,181],[181,182],[182,183],[183,184],[184,185],[185,178],[170,178],[172,180],[174,182],[176,184],[186,187],[187,188],[188,189],[189,190],[190,191],[191,192],[192,193],[193,186],[194,195],[195,196],[196,197],[197,198],[198,199],[199,200],[200,201],[201,194],[186,194],[188,196],[190,198],[192,200],[202,203],[203,204],[204,205],[205,206],[206,207],[207,208],[208,209],[209,210],[210,211],[211,202],[212,213],[213,214],[214,215],[215,216],[216,217],[217,218],[218,219],[219,220],[220,221],[221,212],[202,212],[204,214],[206,216],[208,218],[210,220],[222,223],[223,224],[224,225],[225,226],[226,227],[227,228],[228,229],[229,222],[230,231],[231,232],[232,233],[233,234],[234,235],[235,236],[236,237],[237,238],[238,239],[239,240],[240,241],[241,230],[242,243],[243,244],[244,245],[245,246],[246,247],[247,248],[248,249],[249,250],[250,251],[251,252],[252,253],[253,242],[230,242],[233,245],[236,248],[239,251],[254,255],[255,256],[256,257],[257,258],[258,259],[259,260],[260,261],[261,262],[262,263],[263,254],[264,265],[265,266],[266,267],[267,268],[268,269],[269,270],[270,271],[271,264],[272,273],[273,274],[274,275],[275,276],[276,277],[277,278],[278,279],[279,272],[264,272],[266,274],[268,276],[270,278],[280,281],[281,282],[282,283],[283,284],[284,285],[285,286],[286,287],[287,280],[288,289],[289,290],[290,291],[291,292],[292,293],[293,294],[294,295],[295,288],[280,288],[282,290],[284,292],[286,294],[296,297],[297,298],[298,299],[299,300],[300,301],[301,302],[302,303],[303,304],[304,305],[305,306],[306,307],[307,296],[308,309],[309,310],[310,311],[311,312],[312,313],[313,314],[314,315],[315,316],[316,317],[317,318],[318,319],[319,308],[296,308],[299,311],[302,314],[305,317],[320,321],[321,322],[322,323],[323,324],[324,325],[325,326],[326,327],[327,320],[328,329],[329,330],[330,331],[331,332],[332,333],[333,328],[334,335],[335,336],[336,337],[337,338],[338,339],[339,334],];


评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字

插入代码