挤出几何中的问题

时间:2016-02-24 11:58:18

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

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

enter image description here

  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);
 }

1 个答案:

答案 0 :(得分:0)

不是three.js的粉丝,但在查看代码时,您会遇到一些基本的逻辑错误。

简短回答

for循环中的逻辑错误!将您的第一个代码段更改为以下内容。您在第二个代码段中有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]);
}

现在用我迂腐的眼睛

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

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

应该是

var shape = new THREE.shape();

大写字母仅适用于可以使用new令牌,缩略语或常量的对象。这不是一个简单的约定,因为所有Javascript的内置命名都使用它,我还没有找到一个不使用它的流行框架。不要CAPITALIZE,这是javascript中的一个坏习惯,会导致无休止的时间寻找简单的语法错误。

THREE.Shape对象仅处理2D路径。你有

// 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进行整理。

数组中的项目数是2D点数* 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行`{'或一个小写字符应该是的大写中找到一个丢失的{(小时调试代码,而简单的错误就在你面前隐藏在一堆乱七八糟的地方可以成就或破坏存在编码员)

希望这有帮助..