【问题标题】:Issue in Extruding The Geometry挤压几何的问题
【发布时间】:2016-06-06 16:59:19
【问题描述】:

我正在尝试将画布中绘制的矩形拉伸到 Three.js 画布。 这里蓝色的是 2d 画布,绿色是 3d

  var Shape = new THREE.Shape();
    Shape.moveTo(0,0,0);

    for(var i=0;i<=point.length/2;i++)
    {
        Shape.lineTo(point[i],point[i+1]);
    }


    var ExtrusionSettings = {
        curveSegments: 3,
        bevelThickness:0, bevelSize: 0, bevelEnabled: false,
        material: 0, extrudeMaterial: 1,amount: 10
    };

    var Geometry = new THREE.ExtrudeGeometry( Shape, ExtrusionSettings );
    var Material = new THREE.MeshLambertMaterial({color: 0xff8800});
    Material.side = THREE.DoubleSide;
    Mesh = new THREE.Mesh(Geometry,Material);
    Mesh.position.set(0,0,0);
    Scene.add(Mesh);

点作为数组传递,其中包含画布中线条的 x,y 坐标

点数通过

function mouseDown(event)
{
    Line[0] = event.pageX - this.offsetLeft;
    Line[1] = event.pageY - this.offsetTop;
    console.log("down");

}

function mouseUp(event)
{
    Line[2] =  event.pageX - this.offsetLeft;
    Line[3] =  event.pageY - this.offsetTop;
    console.log("up");

    var Width = Math.abs(Line[2] - Line[0]);
    var Height = Math.abs(Line[3] - Line[1]);



    Context.beginPath();
    //Context.moveTo(Line[0], Line[1]);
    //Context.lineTo(Line[2], Line[3]);

    //Context.rect(Line[0],Line[1],Width,Height);
     Context.lineWidth="5";
    Context.strokeStyle="red";


var L1P1x = Line[0];
var L1P1y = Line[1];
var L1P2x = Line[0]+Width;
var L1p2Y = Line[1];

var L2P1x = Line[0]+Width;
var L2P1y = Line[1];
var L2P2x = Line[2];
var L2P2y = Line[3];

var L3P1x = Line[2];
var L3P1y = Line[3];
var L3P2x = Line[0];
var L3P2y = Line[1]+Height;

var L4P1x = Line[0];
var L4P1y = Line[1]+Height;
var L4P2x = Line[0];
var L4P2y = Line[1];

Context.moveTo(L1P1x,L1P1y);
Context.lineTo(L1P2x,L1p2Y);
Context.moveTo(L2P1x,L2P1y);
Context.lineTo(L2P2x,L2P2y);
Context.moveTo(L3P1x,L3P1y);
Context.lineTo(L3P2x,L3P2y);
Context.moveTo(L4P1x,L4P1y);
Context.lineTo(L4P2x,L4P2y);

Context.stroke();

    Points.push(L1P1x,L1P1y,L1P2x,L1p2Y,L2P1x,L2P1y,L2P2x,L2P2y,L3P1x,L3P1y,L3P2x,L3P2y,L4P1x,L4P1y,L4P2x,L4P2y);
    addMesh(Points);//points are passes to draw in 3d
    //console.log(Points);
 }

【问题讨论】:

    标签: javascript canvas 3d three.js 2d


    【解决方案1】:

    不是three.js 的粉丝,但看看你的代码你有一些基本的逻辑错误。

    简短回答

    for 循环中的逻辑错误!将您的第一个 sn-p 更改为以下内容。您在第二个 sn-p 中有 Points,在第一个中有 Point。我在修复中使用了point,因为我认为这是坐标数组的正确名称。

    var i, len, mesh;      // define all the vars you will use
    len = point.length;   // get the number of coordinates.
    if(len > 1) {         // make sure there are points. 
        shape.moveTo(point[0], point[1]);          // move to the first point
        for(i = 2; i < len; i += 2) {              // iterate other points and lineTo them
           shape.lineTo(point[i], point[i + 1]);   // add the line.
        }
        mesh = new THREE.Mesh(
            new THREE.ExtrudeGeometry(    // Create geom
                shape, 
                {    // extrusion settings.
                    curveSegments   : 3,      
                    bevelThickness  : 0,  
                    bevelSize       : 0, 
                    bevelEnabled    : false,
                    material        : 0, 
                    extrudeMaterial : 1,
                    amount          : 10
                }
            ),      
            new THREE.MeshLambertMaterial({color: 0xff8800}) // material
        );
        mesh.position.set(0, 0 0); // position the mesh  
        scene.add(mesh);           // add it to the scene
    }
    

    这将修复错误。糟糕的是 for 循环。

    长答案。

    您似乎是初学者,所以长答案是给您一些长期建议。 (仅供参考,因为没有规则)。

    创建形状。你有...

    var Shape = new THREE.Shape();
    Shape.moveTo(0,0,0);
    
    for(var i=0;i<=point.length/2;i++)
    {
        Shape.lineTo(point[i],point[i+1]);
    }
    

    现在用我迂腐的眼光

    永远不要用大写来命名变量。大写字母是为命名对象保留的。虽然在这种情况下你是安全的,但在不同的 scopy 中使用名称 Shape 很可能会覆盖对象构造函数。

    var Shape = new THREE.Shape();  // you had
    

    应该是

    var shape = new THREE.shape();
    

    大写字母仅用于您可以将new 标记与首字母缩略词或常量一起使用的对象。这不是一个简单的约定,因为所有 Javascript 的内置命名都使用它,而且我还没有找到一个不使用它的流行框架。不要大写,这是 javascript 中的一个坏习惯,会导致无休止地寻找简单的语法错误。

    THREE.Shape 对象只处理二维路径。你有

    // 3 coordinates for for a 2D path???
    Shape.moveTo(0,0,0);      // remove this line it is not needed
    

    最后一个 0 被忽略,(我检查了 THREE.js 源代码),这不是错误。

    你的错误在下面。

    for(var i=0;i<=point.length/2;i++)  // Only half the points ??
    {   // you then line to x,y
        Shape.lineTo(point[i],point[i+1]);
        // Next lineTo will be y,x then x,y messing everything up.
    }
    

    point 指的是代表路径的 x 和 y 坐标的数字数组。它以x 坐标组织,然后是y,然后是x,然后是y

    数组中的项目数是二维点数*2。*2是因为每个点都有一个X和一个``Y。

    所以需要正确迭代点数组。

    一步一步来。

    var i, len;  // always put your vars declarations at the top
    len = point.length;  // I like to get the length before the loop.
    

    for 循环需要步进 2,因为每个点都有两个条目。

    for(i = 0; i < len; i += 2) {   //Put the { at the end. Saves space and is easier to read.
    

    根据需要检查第一点moveTo(注意答案略有不同)

    if(i === 0) {
    

    将点添加到路径(形状)。

        shape.moveTo(point[i], point[i + 1]);
    

    然后是其他点

    } else {
        shape.lineTo(point[i], point[i + 1]);
    }
    

    这将创建正确的形状,然后您可以使用该形状进行挤压。

    按照我的方式将所有内容放在一起。

    // where do you define scene. It should be lowercase
    var i, len, mesh; 
    len = point.length;  
    if(len > 1) {                          // check if there are points (2 or more.
        shape.moveTo(point[0], point[1]);  // do the first point outside the for loop
                                           // this saves having to do the if statement
                                           // for each point
        for(i = 2; i < len; i += 2) {      // iterate points starting at the second
           shape.moveTo(point[i], point[i + 1]);   // add the line.
        }
    

    你有

        // Such a long name for a one of abd just a mess
        // Your code 
        //var ExtrusionSettings = {
        //    curveSegments: 3,
        //    bevelThickness:0, bevelSize: 0, bevelEnabled: false,
        //    material: 0, extrudeMaterial: 1,amount: 10
        //};
        // unless it will be used again put it inline
    
        // Bad naming for the rest
        // Your code
        //var Geometry = new THREE.ExtrudeGeometry( Shape, ExtrusionSettings );
        //var Material = new THREE.MeshLambertMaterial({color: 0xff8800});
        //Material.side = THREE.DoubleSide;
        //Mesh = new THREE.Mesh(Geometry,Material);
        //Mesh.position.set(0,0,0);
        //Scene.add(Mesh);
    

    全部替换为

        // Material is used once so no need to create var for it
        // Removed Material.side = THREE.DoubleSide;  // assuming this is debug code only
        // you had Mesh without var. That made it global scope. Never use a var without defining it first with the var token
    
        var mesh = new THREE.Mesh(  // define and assign mesh
            new THREE.ExtrudeGeometry(    // Create geom// indent arguments for readability
                shape, 
                {    // extrusion settings.
                    curveSegments   : 3,      // line it all up so you can read it quickly
                    bevelThickness  : 0,  
                    bevelSize       : 0, 
                    bevelEnabled    : false,
                    material        : 0, 
                    extrudeMaterial : 1,
                    amount          : 10
                }
            ),      
            new THREE.MeshLambertMaterial({color: 0xff8800})
        );
    
        mesh.position.set(0,0,0);  // position the mesh
    
        scene.add(mesh);  // add it to the scene
        // note the lowercase scene for the object instance scene. Need to chage that where you create it.    
    } // end of if(len > 1){
    

    那里有很多迂腐的东西,但你显然是编程新手,坏习惯很难改掉,所以从好的开始。错误和调试是编程中最糟糕的部分。调试是所有编程中最耗时的部分(即使对于经验丰富的专业人员也是如此)。所有编程语言中出现错误的最大原因是糟糕的样式和/或混乱的代码。编写干净一致的代码使您的代码更易于阅读,因此更易于调试。尝试在 5000 行 `{' 中找到丢失的 { 或小写字符应该在的大写字母(小时调试代码,而简单的错误就在你面前隐藏在一片混乱中,这可能会成为一名编码员)

    希望这有帮助..

    【讨论】:

      猜你喜欢
      • 2017-12-23
      • 1970-01-01
      • 1970-01-01
      • 2013-01-15
      • 2012-06-10
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多