将几何/网格锚定到它的角落以缩放three.js

时间:2017-02-15 10:18:35

标签: javascript three.js

我基于2个坐标在three.js中创建一个矩形。第一个坐标是第一个用户点击的单元格,第二个坐标是用户拖动光标的位置。

正在创建的rectanlge是正确的大小,但它从它的中心“增长”,而我希望它从第一个用户点击的角落“增长”。我已经尝试了一些可能的解决方案来改变几何的起源,但我还没有找到修复。

The demo can be see here - 使用以下代码。

    var startPoint = startPlace;
    var endPoint = endPlace;
    var zIntersect = new THREE.Vector3(startPoint.x, 0, endPoint.z);
    var xIntersect = new THREE.Vector3(endPoint.x, 0, startPoint.z);

    var differenceZ = Math.abs(startPlace.z - zIntersect.z);
    var differenceX = Math.abs(startPlace.x - xIntersect.x);
    floorGeometryNew.rotateX(-Math.PI / 2);


    var floorGeometryNew = new THREE.PlaneGeometry(differenceX, differenceZ);
    floorGeometryNew.rotateX(-Math.PI / 2);

    var x = startPoint.x;
    var y = startPoint.y;
    var z = startPoint.z;

    var voxel = new THREE.Mesh(floorGeometryNew, tempMaterial);
    voxel.position.set(x, y, z);

2 个答案:

答案 0 :(得分:1)

矩形的中心位于startPointendPoint之间的中间位置,这是它们的平均值:

voxel.position.addVectors(startPoint, endPoint).divideScalar(2);

方法1。每次更改矩形的大小时都不创建新几何体。这个想法是:

  1. 使用双面材质创建一个平面网格
  2. 使用当前交点
  3. 设置平面几何的第一个顶点
  4. 跟踪交点并将其值应用于平面几何的最后一个顶点,并相应地将第二个和第三个顶点更改为第一个和最后一个顶点的位置
  5. 例如,我们在newRect事件上创建了一个平面网格mouseDown,并将其几何体的第一个顶点设置为该时刻的交点:

    newRectGeom.vertices[0].set(onPlanePoint.x, onPlanePoint.y + .5, onPlanePoint.z);
    

    然后在mouseMove上我们得到交点并将其坐标应用到第四个(最后一个)顶点,我们也改变顶点1和2的值:

    newRect.geometry.vertices[1].set(onPlanePoint.x, newRect.geometry.vertices[0].y, newRect.geometry.vertices[0].z);
    newRect.geometry.vertices[2].set(newRect.geometry.vertices[0].x, newRect.geometry.vertices[0].y, onPlanePoint.z);
    newRect.geometry.vertices[3].set(onPlanePoint.x, onPlanePoint.y + .5, onPlanePoint.z);
    

    它比听起来更简单:)

    jsfiddle示例。关闭构建模式 - 启用OrbitControls;构建模式打开 - 控件被禁用,您可以绘制矩形。

    方法2。我们可以控制矩形的位置和缩放,而不是控制顶点。

    mousedown事件中,我们将startPoint设置为交叉点

    startPoint.copy(onPlanePoint);
    

    然后我们将找到矩形的位置和缩放:

    newRect.position.addVectors(startPoint, onPlanePoint).divideScalar(2);
    newRect.position.y = 0.5; // to avoid z-fight
    newRect.scale.set(Math.abs(onPlanePoint.x - startPoint.x), 1, Math.abs(onPlanePoint.z - startPoint.z))
    

    jsfiddle示例。在视觉上和功能上它与Approach 1相同。从我的观点来看,Approach 2更简单。

    enter image description here

答案 1 :(得分:0)

致电时

voxel.position.set(x, y, z);

然后将网格的中心设置为此位置。因此,您必须将矩形的一半长度和一半宽度添加到此位置。使用边界框可以获得这些值。

var bbox = new THREE.Box3();
bbox.setFromObject( voxel );
var val = bbox.max.x - bbox.min.x;