Я пытался построить куб с помощью Tree JS lib, но я не могу правильно нарисовать диагональные и невидимые линии для моего куба. Мой код ниже:
main. js:
'use sctric';
((w, THREE) => {
function getWindowSize() {
return [w.outerWidth, w.outerHeight];
}
const [width, height] = getWindowSize();
const scene = new THREE.Scene();
const aspect = width / height;
const D = 3;
const __ = 1;
const camera = new THREE.OrthographicCamera(
-D * aspect * __,
D * aspect * __,
D,
-D,
1,
1000
);
const renderer = new THREE.CanvasRenderer();
renderer.setSize(width, height);
w.document.body.appendChild(renderer.domElement);
w.onresize = () => {
renderer.setSize(...getWindowSize());
camera.aspect = w.innerWidth / w.innerHeight;
camera.updateProjectionMatrix();
};
var extrudeSettings = {
amount : 1,
steps : 1,
bevelEnabled: true,
curveSegments: 8
};
var arcShape = new THREE.Shape();
arcShape.absarc(0, 0, 1, 0, Math.PI * 2, 0, false);
var holePath = new THREE.Path();
holePath.absarc(0, 0, 0.4, 0, Math.PI * 2, true);
arcShape.holes.push(holePath);
var pyramidgeometry = new THREE.BoxGeometry(1.7, 0.4, 1,1,1);
const material = new THREE.MeshBasicMaterial({color: 0x44aa88});
function removeDuplicateFaces(pyramidgeometry){
for(var i=0; i<pyramidgeometry.faces.length; i++){
var centroid = pyramidgeometry.faces[i].centroid;
for(var j=0; j < i; j++){
var f2 = pyramidgeometry.faces[j];
if( f2 !== undefined ){
var centroid2 = f2.centroid;
if(centroid.equals(centroid2)){
delete pyramidgeometry.faces[i];
delete pyramidgeometry.faces[j];
}
}
}
}
geometry.faces = geometry.faces.filter( function(a){ return a!== undefined });
return geometry;
}
const [heightPrism, dimensionPrism, bottomPolygonPrism] = [2, 40, 1];
const pyramid = new THREE.Mesh(
pyramidgeometry,
new THREE.MeshBasicMaterial({
wireframe: true,
side: THREE.FrontSide,
vertexColors: THREE.FaceColors,
color: 0x000000
})
);
var geometry55 = new THREE.BoxBufferGeometry(1.7, 0.4, 1);
var edges = new THREE.EdgesGeometry( geometry55 );
var line55 = new THREE.LineSegments( edges, new THREE.LineBasicMaterial( { color: 0x2F4F4F } ) );
scene.add( line55 );
pyramid.position.set(0, -0.5, 0);
line55.position.set(0, -0.5, 0);
scene.add(pyramid);
const dashedMaterial = new THREE.LineDashedMaterial({
color: 0x000000,
side: THREE.BackSide,
dashSize: 10,
gapSize: 10, linewidth: 1
});
const cube = new THREE.Line(geo2line(pyramid.geometry), dashedMaterial);
cube.position.set(0, -0.5, 0);
scene.add(cube);
const materialLines = new THREE.LineBasicMaterial({
color: 0x000000
});
const geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3(0, -1, 0),
new THREE.Vector3(0, 2, 0),
new THREE.Vector3(0, -1, 0),
new THREE.Vector3(2, -1, -2),
new THREE.Vector3(0, -1, 0),
new THREE.Vector3(0.3, -1, 2),
new THREE.Vector4(0, -1, 0),
new THREE.Vector4(0.3, -1, 2)
);
const line = new THREE.Line(geometry, materialLines);
scene.add(line);
let spritey = makeTextSprite(" z ", {r: 255, g: 12, b: 0, a: 1.0});
spritey.position.set(0, 2, 0);
scene.add(spritey);
spritey = makeTextSprite(" y ", {r: 255, g: 12, b: 0, a: 1.0});
spritey.position.set(2, -0.8, -2);
scene.add(spritey);
spritey = makeTextSprite(" x ", {r: 255, g: 0, b: 0, a: 1.0});
spritey.position.set(-0.5, -1.5, 1.5);
scene.add(spritey);
camera.position.set(5, 3, 5);
camera.lookAt(scene.position);
pyramid.translate( 1, 0, 0 );
function render1() {
requestAnimationFrame(render1);
cube.rotation.y+= 0.007;
pyramid.rotation.y+= 0.007;
line55.rotation.y+= 0.007;
renderer.render(scene, camera);
}
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
window.onload = init;
function init(){
var button = document.getElementById("addButton")
button.onclick = handleButtonClick;
}
function handleButtonClick() {
requestAnimationFrame(render1);
cube.rotation.y-= 0.009;
pyramid.rotation.y -= 0.009;
renderer.render(scene, camera);
}
function makeTextSprite(message, fontColor, materialColor) {
const fontface = "Georgia";
const fontsize = 90;
const borderThickness = 4;
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
context.font = "Bold " + fontsize + "px " + fontface;
context.fillStyle = "rgba(" + fontColor.r + "," + fontColor.g + "," + fontColor.b + "," + fontColor.a + ")";
context.fillText(message, borderThickness, fontsize + borderThickness);
const texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
const spriteMaterial = new THREE.SpriteMaterial({
map: texture,
color: materialColor !== undefined ? materialColor : 0xffffff
});
const sprite = new THREE.Sprite(spriteMaterial);
const s = .3;
sprite.scale.set(s, s, s);
return sprite;
}
function geo2line(geo)
{
const geometry = new THREE.Geometry();
const vertices = geometry.vertices;
for (let i = 0; i < geo.faces.length; i++) {
const face = geo.faces[i];
if (face instanceof THREE.Face3) {
pyramidgeometry.faces[ i ].color.setHex( Math.random() * 0xffffff );
const b = geo.vertices[face.b].clone();
vertices.push(b);
}
}
geometry.computeLineDistances();
return geometry;
}
})(window, window.THREE);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./style.css">
<title>lab4</title>
</head>
<body>
<script src="./three.min.88.js"></script>
<script src="./Projector.js"></script>
<script src="./CanvasRenderer.js"></script>
<script src="./main.js"></script>
<input type="button" id="addButton" value="Вращение" style="width: 200px" style="height: 50px">
<script>
</script>
</body>
</html>
Могу ли я реализовать свое решение с помощью Three JS?
У меня есть это:
Мое решение Но я хочу иметь это: Правильное решение
Можете ли вы помочь мне с этим? Могу ли я скрыть ненужные диагонали с помощью BoxGeometry, если да - как? Или я должен построить свою коробку с векторами?