Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用three.js具有孔的圆角盒_Javascript_Three.js - Fatal编程技术网

Javascript 使用three.js具有孔的圆角盒

Javascript 使用three.js具有孔的圆角盒,javascript,three.js,Javascript,Three.js,我需要创建一个盒子有四个边圆角,但在顶部和底部。Three.js有一个很好的例子,我试图复制它,在绿色的圆形框中添加一个洞。在本例中,要向圆中添加孔,请执行以下操作: // Arc circle var arcShape = new THREE.Shape() .moveTo( 50, 10 ) .absarc( 10, 10, 40, 0, Math.PI * 2, false );

我需要创建一个盒子有四个边圆角,但在顶部和底部。Three.js有一个很好的例子,我试图复制它,在绿色的圆形框中添加一个洞。在本例中,要向圆中添加孔,请执行以下操作:

        // Arc circle

            var arcShape = new THREE.Shape()
                .moveTo( 50, 10 )
                .absarc( 10, 10, 40, 0, Math.PI * 2, false );

            var holePath = new THREE.Path()
                .moveTo( 20, 10 )
                .absarc( 10, 10, 10, 0, Math.PI * 2, true )

            arcShape.holes.push( holePath );
它们创建一个形状和一个路径,然后添加孔。结果是

我对四舍五入的正方形使用了同样的逻辑

原始形状

 // Rounded rectangle

            var roundedRectShape = new THREE.Shape();

            ( function roundedRect( ctx, x, y, width, height, radius ) {

                ctx.moveTo( x, y + radius );
                ctx.lineTo( x, y + height - radius );
                ctx.quadraticCurveTo( x, y + height, x + radius, y + height );
                ctx.lineTo( x + width - radius, y + height );
                ctx.quadraticCurveTo( x + width, y + height, x + width, y + height - radius );
                ctx.lineTo( x + width, y + radius );
                ctx.quadraticCurveTo( x + width, y, x + width - radius, y );
                ctx.lineTo( x + radius, y );
                ctx.quadraticCurveTo( x, y, x, y + radius );

            } )( roundedRectShape, 0, 0, 50, 50, 20 );
            var roundedRectShape_small = new THREE.Path();

            ( function roundedRect( ctx, x, y, width, height, radius ) {

                ctx.moveTo( x, y + radius );
                ctx.lineTo( x, y + height - radius );
                ctx.quadraticCurveTo( x, y + height, x + radius, y + height );
                ctx.lineTo( x + width - radius, y + height );
                ctx.quadraticCurveTo( x + width, y + height, x + width, y + height - radius );
                ctx.lineTo( x + width, y + radius );
                ctx.quadraticCurveTo( x + width, y, x + width - radius, y );
                ctx.lineTo( x + radius, y );
                ctx.quadraticCurveTo( x, y, x, y + radius );

            } )( roundedRectShape_small, 10, 10, 30, 30, 20 );
新孔形状

 // Rounded rectangle

            var roundedRectShape = new THREE.Shape();

            ( function roundedRect( ctx, x, y, width, height, radius ) {

                ctx.moveTo( x, y + radius );
                ctx.lineTo( x, y + height - radius );
                ctx.quadraticCurveTo( x, y + height, x + radius, y + height );
                ctx.lineTo( x + width - radius, y + height );
                ctx.quadraticCurveTo( x + width, y + height, x + width, y + height - radius );
                ctx.lineTo( x + width, y + radius );
                ctx.quadraticCurveTo( x + width, y, x + width - radius, y );
                ctx.lineTo( x + radius, y );
                ctx.quadraticCurveTo( x, y, x, y + radius );

            } )( roundedRectShape, 0, 0, 50, 50, 20 );
            var roundedRectShape_small = new THREE.Path();

            ( function roundedRect( ctx, x, y, width, height, radius ) {

                ctx.moveTo( x, y + radius );
                ctx.lineTo( x, y + height - radius );
                ctx.quadraticCurveTo( x, y + height, x + radius, y + height );
                ctx.lineTo( x + width - radius, y + height );
                ctx.quadraticCurveTo( x + width, y + height, x + width, y + height - radius );
                ctx.lineTo( x + width, y + radius );
                ctx.quadraticCurveTo( x + width, y, x + width - radius, y );
                ctx.lineTo( x + radius, y );
                ctx.quadraticCurveTo( x, y, x, y + radius );

            } )( roundedRectShape_small, 10, 10, 30, 30, 20 );
然后我加上这个洞

roundedRectShape.holes.push( roundedRectShape_small );
结果不一样


正如你所看到的,这个洞在里面,但是3D效果在里面是错误的。如何修复它?

您必须按相反的缠绕顺序绘制孔。由于外部矩形路径为顺时针绘制,因此孔路径必须逆时针绘制:

设f_rect=函数roundedRect(ctx,x,y,宽度,高度,半径){
ctx.移动到(x,y+半径);
ctx.lineTo(x,y+高度-半径);
ctx.直角曲线(x,y+高度,x+半径,y+高度);
ctx.lineTo(x+宽度-半径,y+高度);
ctx.直角曲线(x+宽度,y+高度,x+宽度,y+高度-半径);
ctx.lineTo(x+宽度,y+半径);
ctx.四次曲线(x+宽度,y,x+宽度-半径,y);
ctx.lineTo(x+半径,y);
ctx.四次曲线(x,y,x,y+半径);
}
设f_rect_reverse=函数roundedRect(ctx,x,y,宽度,高度,半径){
ctx.moveTo(x,y+高度-半径);
ctx.lineTo(x,y+半径);
ctx.二次曲线(x,y,x+半径,y);
ctx.lineTo(x+宽度-半径,y);
ctx.直角曲线(x+宽度,y,x+宽度,y+半径);
ctx.lineTo(x+宽度,y+高度-半径);
ctx.直角曲线(x+宽度,y+高度,x+宽度-半径,y+高度);
ctx.lineTo(x+半径,y+高度);
ctx.直角曲线(x,y+高度,x,y+高度-半径);
}
var roundedRectShape=new THREE.Shape();
f_rect(圆形矩形,-25,-25,50,50,20);
var roundedRectShape_small=new THREE.Path();
f_rect_reverse(圆形矩形_small,-15,-15,30,30,10);
roundedRectShape.holes.push(roundedRectShape_small);

请参见完整示例:

(函数onLoad(){
var容器、摄影机、场景、渲染器、控件;
init();
制作动画();
函数init(){
container=document.getElementById('container');
renderer=new THREE.WebGLRenderer({
反别名:对
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth、window.innerHeight);
renderer.shadowMap.enabled=true;
container.appendChild(renderer.domeElement);
场景=新的三个。场景();
scene.background=新的三种颜色(0xffffff);
摄像头=新的三个透视摄像头(70,window.innerWidth/window.innerHeight,11000);
摄像机。位置。设置(3,2,7);
场景。添加(摄影机);
window.onresize=函数(){
renderer.setSize(window.innerWidth、window.innerHeight);
camera.aspect=window.innerWidth/window.innerHeight;
camera.updateProjectMatrix();
}
var环境光=新的三个环境光(0x404040);
场景。添加(环境光);
var方向光=新的三个方向光(0xffffff,0.5);
方向光位置x=4;
方向光位置y=1;
方向灯位置z=2;
场景。添加(方向光);
控件=新的三个.轨道控件(摄影机、渲染器.doElement);
addGridHelper();
createModel();
}
函数createModel(){
设f_rect=函数roundedRect(ctx,x,y,宽度,高度,半径){
ctx.移动到(x,y+半径);
ctx.lineTo(x,y+高度-半径);
ctx.直角曲线(x,y+高度,x+半径,y+高度);
ctx.lineTo(x+宽度-半径,y+高度);
ctx.直角曲线(x+宽度,y+高度,x+宽度,y+高度-半径);
ctx.lineTo(x+宽度,y+半径);
ctx.四次曲线(x+宽度,y,x+宽度-半径,y);
ctx.lineTo(x+半径,y);
ctx.四次曲线(x,y,x,y+半径);
}
设f_rect_reverse=函数roundedRect(ctx,x,y,宽度,高度,半径){
ctx.moveTo(x,y+高度-半径);
ctx.lineTo(x,y+半径);
ctx.二次曲线(x,y,x+半径,y);
ctx.lineTo(x+宽度-半径,y);
ctx.直角曲线(x+宽度,y,x+宽度,y+半径);
ctx.lineTo(x+宽度,y+高度-半径);
ctx.直角曲线(x+宽度,y+高度,x+宽度-半径,y+高度);
ctx.lineTo(x+半径,y+高度);
ctx.直角曲线(x,y+高度,x,y+高度-半径);
}
var roundedRectShape=new THREE.Shape();
f_rect(圆形矩形,-25,-25,50,50,20);
var roundedRectShape_small=new THREE.Path();
f_rect_reverse(圆形矩形_small,-15,-15,30,30,10);
roundedRectShape.holes.push(roundedRectShape_small);
var material=new THREE.MeshLambertMaterial({color:0x00ff00,side:THREE.DoubleSide});
var extruptesettings={depth:8,bevelEnabled:true,bevelSegments:2,steps:3,bevelSize:5,bevelChickness:5};
var geometry=新的三个.ExtrudeBufferGeometry(圆形拉伸形状,挤出设置);
设s=0.1;
var mesh=新的三个网格(几何体、材质);
网格.比例.集(s,s,s);
场景。添加(网格);
}
函数addGridHelper(){
var helper=新的三个.GridHelper(10,10);
helper.material.opacity=0.25;
helper.material.transparent=true;
场景.添加(助手);
var轴=新的三轴辅助(100);
场景。添加(轴);
}
函数animate(){
请求动画帧(动画);
render();
}
函数render(){
渲染器。渲染(场景、摄影机)