Round Corners Box Geometry - threejs

时间:2018-02-27 12:06:02

标签: javascript math three.js geometry

这个问题更多的是关于数学,而不是大约三个,但也许我的问题有可用的替代品。

Example Image for issue

所以我想要做的就是遍历Box Geometry中的每个顶点并检查它是否必须向下/向上移动然后按特定值移动它。 (它只是关于每个顶点的y值)

var width = 200,
    height = 100,
    depth = 50;
var roundCornerWidth = var roundCornerHeight = 10;
var helpWidth = width - 2*roundCornerWidth,
    helpHeight = height - 2*roundCornerHeight;

var boxGeometry = new THREE.BoxGeometry(width, height, depth, 100, 50, 10);
boxGeometry.vertices.forEach(v => {
  if(Math.abs(v.x)>helpWidth/2){
    if(Math.abs(v.y)>helpHeight/2){
      let helper = Math.abs(v.x)-helperWidth/2;
      v.y = Math.sign(v.y)*(helperHeight + Math.cos(helper/roundWidth * Math.PI/2)*roundHeight);
    }
  }
});

上面的代码会像您在示例图像上看到的那样创建角落。那些不是那么漂亮! :(另一个"功能"需要cos()

2 个答案:

答案 0 :(得分:1)

我使用了没有三角函数的方法,因为我们可以用向量来操作:



var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(50, 50, 150);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var radius = 10;
var width = 200,
  height = 100;
var geometry = new THREE.BoxGeometry(width, height, 50, 100, 50, 10);

var v1 = new THREE.Vector3();
var w1 = (width - (radius * 2)) * 0.5,
  h1 = (height - (radius * 2)) * 0.5;
var vTemp = new THREE.Vector3(),
  vSign = new THREE.Vector3(),
  vRad = new THREE.Vector3();
geometry.vertices.forEach(v => {
  v1.set(w1, h1, v.z);
  vTemp.multiplyVectors(v1, vSign.set(Math.sign(v.x), Math.sign(v.y), 1));
  vRad.subVectors(v, vTemp);
  if (Math.abs(v.x) > v1.x && Math.abs(v.y) > v1.y && vRad.length() > radius) {
    vRad.setLength(radius).add(vTemp);
    v.copy(vRad);
  }
});

var mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
  color: "aqua",
  wireframe: true
}));
scene.add(mesh);

render();

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}

body {
  overflow: hidden;
  margin: 0;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/90/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
&#13;
&#13;
&#13;

缺点:您无法在不增加宽度或高度或深度段的情况下控制圆度的平滑度。

答案 1 :(得分:-1)

编辑:从prisoner849复制了周围的代码块,为每个人创建了结果可访问性。

我想继续使用Geometry框,因为我也在z轴上变形Geometry,所以这是我的解决方案:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(50, 50, 150);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);
var width = 200,
    height = 100,
    depth = 50;
var roundCornerWidth = roundCornerHeight = 10;
var helpWidth = width - 2*roundCornerWidth,
    helpHeight = height - 2*roundCornerHeight;

var boxGeometry = new THREE.BoxGeometry(width, height, depth, 100, 50, 10);
boxGeometry.vertices.forEach(v => {
  if(Math.abs(v.x)>helpWidth/2){
    if(Math.abs(v.y)>helpHeight/2){
      let helperX = Math.abs(v.x)-helpWidth/2;
      let helperY2 = (Math.abs(v.y)-helpHeight/2)/roundCornerHeight;
      let helperY = (1-helperX/roundCornerWidth) * roundCornerHeight * helperY2;
      v.y = Math.sign(v.y)*((helpHeight/2 + helperY)+(Math.sin(helperX/roundCornerWidth * Math.PI)*(roundCornerHeight/4))*helperY2);
      v.x = Math.sign(v.x)*(Math.abs(v.x)+(Math.sin(helperX/roundCornerWidth * Math.PI)*(roundCornerWidth/4))*helperY2);
    }
  }
});

var mesh = new THREE.Mesh(boxGeometry, new THREE.MeshBasicMaterial({
  color: 0xffce00,
  wireframe: true
}));
scene.add(mesh);

render();

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
 
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/90/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

这对我来说非常合适,对我来说似乎是最简单的解决方案。