javascript - 如何根据 x、y 和 z 在 3D 矩形中画线?

标签 javascript actionscript-3 3d

enter image description here

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

此处投影类型为正交。

谢谢

最佳答案

好的。让我们看一个简单的示例,说明您要实现的目标,以及为什么这是一个如此复杂的问题。

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

最容易理解的是一个非常简单的二轴投影。像这样的东西:

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

这是什么意思?嗯,x' 是你的 x 坐标二维投影:对于你在空间中向后移动的每个单位,投影会将那个点向右边移动一半的单位。 y' 代表您的 y 坐标的相同投影:对于您在空间中向后 移动的每个单位,投影 都会将该点移动四分之一单位起来

因此 [0,0,0] 处的点将投影到 [0,0] 的二维点。 [0,0,4] 处的点将投影到 [2,1] 的二维点。

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

这是一个非常简单的函数,我们将 Canvas 上下文注入(inject)为 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 背后的数学知识,有大量在线资源和打印形式的资源。一旦您对数学工作原理有了更深入的了解,如果您有具体的实现问题,请返回此处。

关于javascript - 如何根据 x、y 和 z 在 3D 矩形中画线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12267839/

相关文章:

javascript - 该代码使用哪种语言/脚本?

javascript - 如何从铁型 polymer 中获取响应头

python - 使用 python 将 3D 网格渲染成图像

javascript - 如何在 HTML5 Canvas 中显示 tQuery.World

javascript - 如何单击按钮 ID 并在具有相同 ID 的 div 上进行更改?

javascript - 按用户 ID 和日期范围查询 Firestore?

flash - 如果一个对象在 Flash 中被垃圾回收,它引用的对象的引用计数器会自动递减吗?

actionscript-3 - 在 AS3 的事件监听器中使用弱引用的(缺点)优点是什么?

JavaScript onClick函数触发ActionsScript3事件

graphics - 4x4矩阵最后一个元素的意义?