我正在我的第一个Three.js项目中,遇到一些奇怪的问题。我正在阅读this paper关于测地穹顶的信息,并尝试渲染它们。
我已经弄清楚了如何绘制二十面体,以及如何将其划分为n度测地线圆顶。但是,当我绘制测地穹顶时,似乎没有填充面(参见图片)。我正在使用THREE.PolyhedronGeometry
,它似乎定义了所有面,否则不应显示没有面的线框边缘,但它们确实会出现...
这是我生成测地线圆顶三角形的代码
// http://www.geometer.org/mathcircles/geodesic.pdf
// Golden Ratio
const g = (1 + Math.sqrt(5)) / 2
type Point = [number, number, number]
type Triangle = [Point, Point, Point]
// Points
const A: Point = [0, 1, g]
const B: Point = [0, -1, g]
const C: Point = [0, -1, -g]
const D: Point = [0, 1, -g]
const E: Point = [g, 0, 1]
const F: Point = [-g, 0, 1]
const G: Point = [-g, 0, -1]
const H: Point = [g, 0, -1]
const I: Point = [1, g, 0]
const J: Point = [-1, g, 0]
const K: Point = [-1, -g, 0]
const L: Point = [1, -g, 0]
// Triangles
const icosahedron: Triangle[] = [
[A, I, J],
[A, J, F],
[A, F, B],
[A, B, E],
[A, E, I],
[B, F, K],
[B, K, L],
[B, L, E],
[C, D, H],
[C, H, L],
[C, L, K],
[C, K, G],
[C, G, D],
[D, G, J],
[D, J, I],
[D, I, H],
[E, L, H],
[E, H, I],
[F, J, G],
[F, G, K],
]
const edge = 2
const radius = Math.sqrt(1 + g * g)
function sub(p1: Point, p2: Point): Point {
return [p1[0] - p2[0], p1[1] - p2[1], p1[2] - p2[2]]
}
function mult(n: number, p1: Point): Point {
return [p1[0] * n, p1[1] * n, p1[2] * n]
}
function add(p1: Point, p2: Point): Point {
return [p1[0] + p2[0], p1[1] + p2[1], p1[2] + p2[2]]
}
function distance(p1: Point, p2: Point): number {
const x = sub(p1, p2)
return Math.sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2])
}
function split(tri: Triangle): Array<Triangle> {
const midpoint01 = add(mult(0.5, tri[0]), mult(0.5, tri[1]))
const midpoint02 = add(mult(0.5, tri[0]), mult(0.5, tri[2]))
const midpoint12 = add(mult(0.5, tri[1]), mult(0.5, tri[2]))
const scale = radius / distance(midpoint01, [0, 0, 0])
const m01 = mult(scale, midpoint01)
const m02 = mult(scale, midpoint02)
const m12 = mult(scale, midpoint12)
return [
[m01, m02, m12],
[tri[0], m01, m02],
[tri[1], m01, m12],
[tri[2], m02, m12],
]
}
const geodome1 = _.flatten(icosahedron.map(split))
const geodome2 = _.flatten(geodome1.map(split))
这是我的Three.js代码,用于渲染多面体:
function trianglesToPoly(triangles: Triangle[]) {
const points: Point[] = _.uniqWith(_.flatten(triangles), _.isEqual)
const vertices = _.flatten(points)
const faces = _.flatten(
_.flatten(
triangles.map(triangle => {
return triangle.map(point => {
return points.findIndex(p => _.isEqual(p, point))
})
})
)
)
const geometry = new THREE.PolyhedronGeometry(vertices, faces, 10, 0)
return geometry
}
const scene = new THREE.Scene()
const width = window.innerWidth * 0.8
const height = window.innerHeight * 0.8
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)
const renderer = new THREE.WebGLRenderer()
renderer.setSize(width, height)
renderer.domElement.style.height = `${height}px`
renderer.domElement.style.width = `${width}px`
document.body.appendChild(renderer.domElement)
// const geometry = trianglesToPoly(icosahedron)
const geometry = trianglesToPoly(geodome1)
// const geometry = trianglesToPoly(geodome2)
var material = new THREE.MeshPhongMaterial({
color: 0x0000ff,
polygonOffset: true,
polygonOffsetFactor: 1, // positive value pushes polygon further away
polygonOffsetUnits: 1,
})
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
// https://stackoverflow.com/questions/31539130/display-wireframe-and-solid-color
var geo = new THREE.EdgesGeometry(mesh.geometry) // or WireframeGeometry
var mat = new THREE.LineBasicMaterial({ color: 0xffffff, linewidth: 4 })
var wireframe = new THREE.LineSegments(geo, mat)
mesh.add(wireframe)
camera.position.z = 50
const animate = () => {
requestAnimationFrame(animate)
mesh.rotation.x += 0.01
mesh.rotation.y += 0.01
renderer.render(scene, camera)
}
animate()
为什么这些面孔没有露面?我什至找不到面部的颜色定义位置,或者我给它加一个颜色使其更明显。
如果您克隆我的仓库,您可以自己运行代码:
git clone https://github.com/ccorcos/geodome.git
cd geodome
npm install
npm start