【问题标题】:find upper face of cube on demand按需查找立方体的上表面
【发布时间】:2016-03-14 15:15:46
【问题描述】:

我要解决的一般问题是找出立方体的哪个面朝上。立方体可以在任何方向一次滚动 90°。如果某个面朝上,立方体就会消失。我正在使用补间来旋转立方体并改变它的位置。

我目前正试图通过创建一条新射线来解决这个问题,它的原点设置在立方体的正上方,它的方向向下短距离,所以它只与立方体的上表面相交。 violet thingy on top of die is ray cast downward into the cube

到目前为止一切顺利。当我检查console.log() 时,我将我的立方体作为相交对象,但是当我尝试通过faceIntersect.face 访问相交面时,它似乎是未定义的。

有问题的功能:

function checkUpperFace(posX, posZ) {

  // get position from passed x- and z-values (y is always above cube)
  // and set direction and length of ray
  var position = new THREE.Vector3( posX, 3, posZ );
  var direction = new THREE.Vector3(0, -1, 0);
  var far = 2;
  // create ray, that goes downwards from above the cube
  var cubeRaycaster = new THREE.Raycaster( position, direction, 0, far );
  // get intersection with upper face of rolled cube
  var faceIntersect = cubeRaycaster.intersectObject( currentCube );

  // add a helper to see the ray
  var arrowHelper = new THREE.ArrowHelper( direction, position, far, 0x770077 );
  scene.add( arrowHelper );

  console.log(faceIntersect); // object is shown with everything I want to know
  console.log(faceIntersect.face); // is shown to be undefined

}

【问题讨论】:

    标签: three.js 3d intersection raycasting


    【解决方案1】:

    可能不是您的光线投射问题的解决方案,而是另一种方法:您为什么不简单地通过比较旋转欧拉角来检测上表面?例如。 (伪代码):

    if(cube.rotation.x % 360 == 0)
    {
        // upper face upwards
    }
    else if(cube.rotation.x % 360 == 90)
    {
        // left face upwards
    }
    

    您将不得不处理值公差 (85° - 95°) 负旋转值和超出 PI*2 范围的值,但除此之外,不是更容易吗?

    【讨论】:

    • 我猜这会更容易,我直到现在才这样做的唯一原因是因为我想避免一个相当长的 if-else 语句和很多其他语句。但如果我无法解决我的光线投射问题,我可能会这样做,所以谢谢。 :)
    【解决方案2】:

    最后我以@unx 推荐的方式做到了,但我真的想避免使用巨大的 if-else 语句,所以我使用了一个数组 rotationLibrary,它具有所有可能的旋转,对应的顶面死。但是由于我用来旋转和移动骰子的补间,它的旋转值并不是真的在点上,因此很难与我在数组中使用它们时的固定旋转值进行比较。

    所以我将骰子的旋转值“标准化”为可用于将它们与rotationLibrary 中的值进行比较的值。最后一步是存储/更新立方体对象本身顶部面的结果,以便我可以随时获取它。

    // spawn condition:
    // 1 on top, 2 facing camera, 3 facing right (seen from camera),
    // 4 facing left (see 3), 5 facing away from camera, 6 facing down
    var rotationLibrary = [
        {x: 0,      y: 0,   z: 0,   face: 1},
        {x: 0,      y: 90,  z: 0,   face: 1},
        {x: 180,    y: 0,   z: 180, face: 1},
        {x: 0,      y: -90, z: 0,   face: 1},
        {x: -90,    y: 0,   z: 0,   face: 2},
        {x: -90,    y: 0,   z: 90,  face: 2},
        {x: -90,    y: 0,   z: 180, face: 2},
        {x: -90,    y: 0,   z: -90, face: 2},
        {x: 0,      y: 0,   z: 90,  face: 3},
        {x: 90,     y: 90,  z: 0,   face: 3},
        {x: -90,    y: -90, z: 0,   face: 3},
        {x: -90,    y: 90,  z: 180, face: 3},
        {x: 180,    y: 0,   z: -90, face: 3},
        {x: 0,      y: 0,   z: -90, face: 4},
        {x: 90,     y: -90, z: 0,   face: 4},
        {x: -90,    y: 90,  z: 0,   face: 4},
        {x: 180,    y: 0,   z: 90,  face: 4},
        {x: 90,     y: 0,   z: 0,   face: 5},
        {x: 90,     y: 0,   z: -90, face: 5},
        {x: 90,     y: 0,   z: 180, face: 5},
        {x: 90,     y: 0,   z: 90,  face: 5},
        {x: 90,     y: 90,  z: 90,  face: 5},
        {x: 0,      y: 0,   z: 180, face: 6},
        {x: 180,    y: -90, z: 0,   face: 6},
        {x: 180,    y: 90,  z: 0,   face: 6},
        {x: 180,    y: 0,   z: 0,   face: 6}
    ];
    
    function checkRotationsToGetUpperFace(cube) {
      // create object with "normalized" (brought to quarter-circle-degree-values) degrees
      var normalizedRotation = {
        x: 0,
        y: 0,
        z: 0
      };
      normalizedRotation.x = getNormalizedDegree(cube.rotation._x);
      normalizedRotation.y = getNormalizedDegree(cube.rotation._y);
      normalizedRotation.z = getNormalizedDegree(cube.rotation._z);
    
      // go through the library that has all the degrees with the corresponding upper face
      for (var i = 0; i < rotationLibrary.length; i++) {
        // check if the objects match, then get the face
        if (rotationLibrary[i].x == normalizedRotation.x &&
          rotationLibrary[i].y == normalizedRotation.y &&
          rotationLibrary[i].z == normalizedRotation.z) {
          cube.face = rotationLibrary[i].face;
        }
      }
    
      // reattach cube for correct movement later
      THREE.SceneUtils.attach(cube, scene, pivot);
    }
    
    function getNormalizedDegree(rotationValue) {
        // transform rotation value into degree value
      var rotValue = rotationValue / (Math.PI / 180);
    
      // default value is 0, so only check if it should be 90°, 180° or -90°
      var normalizedDegree = 0;
      // x between 45° and 135° ( ~ 90)
      if (rotValue > 45 && rotValue < 135) {
        normalizedDegree = 90;
      }
      // x between -45° and -135° ( ~ -90)
      else if (rotValue < -45 && rotValue > -135) {
        normalizedDegree = -90;
      }
      // x between 135° and 215° or x between -135° and -215° ( ~ 180)
      else if ((rotValue > 135 && rotValue < 215) || (rotValue < -135 && rotValue > -215)) {
        normalizedDegree = 180;
      }
    
      return normalizedDegree;
    }
    

    (http://jsfiddle.net/b2an3pq7/3/)

    【讨论】:

      猜你喜欢
      • 2016-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多