如何基于x,y和z在3D矩形中绘制线条?

时间:2012-09-04 16:38:27

标签: javascript actionscript-3 3d

enter image description here

我想将图像中表示的3D点绘制为3D矩形。我知道如何在x,y和z轴上表示这些

此处投影类型为拼写。

由于

3 个答案:

答案 0 :(得分:3)

好。让我们看一个你想要完成它的简单例子,以及为什么这是一个如此复杂的问题。

首先,让我们看看一些投影函数。您需要一种方法来数学描述如何将3D(或更高维度)点转换为2D空间(您的监视器)或投影

最简单的理解是一个非常简单的二维投影。类似的东西:

x' = x + z/2;
y' = y + z/4;

这是什么意思?那么,x'是你x坐标2D 投影:对于你在空间中向后移动的每个单位,投影将移动那个点的一半多少单位。并且y'表示y坐标的相同投影:对于在空间中向后的每个单位,投影会将该点移动四分之一单位

因此,[0,0,0]处的某个点将被投射到[0,0]的2d点。 [0,0,4]处的点将被投射到[2,1]的2d点。

在JavaScript中实现,它看起来像这样:

// Dimetric projection functions
var dimetricTx = function(x,y,z) { return x + z/2; };
var dimetricTy = function(x,y,z) { return y + z/4; };

一旦您拥有这些投影功能 - 或者从3D空间转换为2D空间的方法 - 您可以使用它们开始绘制图像。一个简单的例子,使用js canvas。首先,一些上下文的东西:

var c = document.getElementById("cnvs");
var ctx = c.getContext("2d");

现在,让我们做一个小帮手画一个3D点:

  var drawPoint = (function(ctx,tx,ty, size) {
    return function(p) {
      size = size || 3;

      // Draw "point"
      ctx.save();
      ctx.fillStyle="#f00";
      ctx.translate(tx.apply(undefined, p), ty.apply(undefined,p));
      ctx.beginPath();
      ctx.arc(0,0,size,0,Math.PI*2);
      ctx.fill();
      ctx.restore();
    };
  })(ctx,dimetricTx,dimetricTy);

这是非常简单的函数,我们将画布上下文注入为ctx,以及我们的txty函数,在本例中我们是我们之前看到的二次函数

现在是一个多边形抽屉:

  var drawPoly = (function(ctx,tx,ty) {
    return function() {
      var args = Array.prototype.slice.call(arguments, 0);

      // Begin the path
      ctx.beginPath();

      // Move to the first point
      var p = args.pop();
      if(p) {
        ctx.moveTo(tx.apply(undefined, p), ty.apply(undefined, p));
      }

      // Draw to the next point
      while((p = args.pop()) !== undefined) {
        ctx.lineTo(tx.apply(undefined, p), ty.apply(undefined, p));
      }

      ctx.closePath();
      ctx.stroke();

    };
  })(ctx, dimetricTx, dimetricTy);

使用这两个功能,您可以有效地绘制您正在寻找的图形。例如:

// The array of points
var points = [
  // [x,y,z]
  [20,30,40],
  [100,70,110],
  [30,30,75]
];

(function(width, height, depth, points) {
  var c = document.getElementById("cnvs");
  var ctx = c.getContext("2d");

  // Set some context
  ctx.save();
  ctx.scale(1,-1);
  ctx.translate(0,-c.height);

  ctx.save();

  // Move our graph
  ctx.translate(100,20);  

  // Draw the "container"
  ctx.strokeStyle="#999";
  drawPoly([0,0,depth],[0,height,depth],[width,height,depth],[width,0,depth]);

  drawPoly([0,0,0],[0,0,depth],[0,height,depth],[0,height,0]);
  drawPoly([width,0,0],[width,0,depth],[width,height,depth],[width,height,0]);
  drawPoly([0,0,0],[0,height,0],[width,height,0],[width,0,0]);
  ctx.stroke();

  // Draw the points
  for(var i=0;i<points.length;i++) {
    drawPoint(points[i]);
  }

})(150,100,150,points);

但是,您现在应该能够开始看到实际问题的一些复杂性。也就是说,你问过旋转,在这个例子中我们使用了一个非常简单的投影(我们的二维投影),除了深度及其对x,y位置的影响之间的过度简化关系之外,它不需要太多。随着投影变得更加复杂,您需要更多地了解3D空间中的关系/方向,以便创建合理的2D投影。

上述代码的工作示例可以是found here。该示例还包括等距投影函数,可以将其替换为二维投影函数,以查看它如何改变图形的外观。它还做了一些我在这里没有包含的不同的可视化内容,比如绘制“阴影”以帮助“可视化”实际方向 - 3D到2D投影的局限性。

这很复杂,甚至一个肤浅的讨论都超出了这个stackoverflow的范围。我建议你多读一下3D背后的数学,有很多资源,包括在线和印刷形式。一旦你对数学如何运作的基础有了更深刻的理解,那么如果你有一个特定的实现问题,请返回这里。

答案 1 :(得分:2)

你想做的事情是不可能使用你所说的方法 - 这是因为一个盒子 - 当以3维旋转时看起来不像你的那个图。它也会根据您需要的投影类型而有所不同。但是,您可以开始使用three.js这是一个用于Javascript的3D绘图库。

希望这有帮助。

答案 2 :(得分:1)

如何绘制3D矩形? 发表于:平行四边形|更新时间:2012年9月14日

要绘制3维矩形意味着我们正在处理与2-D图形不同的图形,这些图形需要3个轴来表示它们。那么,如何绘制3D矩形?

首先,首先在纸张中间制作两条线,一条垂直线和另一条水平线,使它们代表英文的“t”字母。这是我们需要绘制以供临时使用的内容,并将在完成三维矩形的构建后删除。接下来我们绘制一个Square,其每边的尺寸为1英寸。方形必须在几何上是完美的,以便在各个角上形成的90度角是精确的。现在从正方形的右上角开始绘制一条线段,该线段将以45度的角度拉伸到2英寸的尺寸。类似地,我们通过从正方形的左上角绘制另一个线段并在45度角的方向上将其拉伸到2英寸长度来重复该过程。这两个线段被认为是我们在开始时临时绘制的水平线的对角线。这些线也将彼此平行。接下来,我们绘制一条连接这两个对角线的终点的线。

接下来从2英寸对角线终点的最右边开始,绘制一条1英寸的测量线,该线应该垂直于临时水平线。接下来我们需要加入广场的左下角和我们在第4步绘制的最后1'线的终点,最后得到我们的3-D矩形。现在我们可以删除我们的初始“t”。这个三维矩形类似于长方体。