如何根据 x、y 和 z 在 3D 矩形中画线? [英] How to Draw line in 3D rectangle based on x,y and z?

查看:30
本文介绍了如何根据 x、y 和 z 在 3D 矩形中画线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like draw 3D points represented in image to 3D rectangle. Any idea how could I represent these in x,y and z axis

这里的投影类型是正交的.

Here projection type is orthographic.

谢谢

推荐答案

好的.让我们看一个简单的例子,说明您要完成的任务,以及为什么这是一个如此复杂的问题.

Okay. Let's look at a simple example of what you are trying to accomplish it, and why this is such a complicated problem.

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

First, lets look a some projection functions. You need a way to mathematically describe how to transform a 3D (or higher dimensional) point into a 2D space (your monitor), or a projection.

最容易理解的是一个非常简单的二等距投影.类似的东西:

The simpiest to understand is a very simple dimetric projection. Something like:

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

这是什么意思?好吧,x' 是你的 x 坐标 2D 投影:对于你在空间中向后移动的每个单位,投影将该点移动到右侧的一半单位.并且 y' 代表您的 y 坐标的相同投影:对于您在空间中向后移动的每个单位,投影将使该点移动四分之一单位向上.

What does this mean? Well, x' is you x coordinate 2D projection: for every unit you move backwards in space, the projection will move that point half that many units to the right. And y' represents that same projection for your y coordinate: for every unit you move backwards in space, the projection will move that point a quarter unit up.

所以 [0,0,0] 处的点将被投影到 [0,0] 的二维点.[0,0,4] 处的点将被投影到 [2,1] 的二维点.

So a point at [0,0,0] will get projected to a 2d point of [0,0]. A point at [0,0,4] will get projected to a 2d point of [2,1].

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

Implemented in JavaScript, it would look something like this:

// 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 画布的简单示例.首先,一些上下文的东西:

Once you have these projection functions -- or ways to translate from 3D space into 2D space -- you can use them to start draw your image. A simple example of that using js canvas. First, some context stuff:

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

现在,让我们制作一个小助手来绘制 3D 点:

Now, lets make a little helper to draw a 3D point:

  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 函数,它们在这个例子就是我们之前看到的二元函数.

This is pretty simple function, we are injecting the canvas context as ctx, as well as our tx and ty functions, which in this case our the dimetric functions we saw earlier.

现在是多边形抽屉:

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

使用这两个函数,您可以有效地绘制您正在寻找的图形类型.例如:

With those two functions, you could effectively draw the kind of graph you are looking for. For example:

// 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 投影.

However, you should now be able to start to see some of the complexity of your actual question emerge. Namely, you asked about rotation, in this example we are using an extremely simple projection (our dimetric projection) which doesn't take much other than an oversimplified relationship between depth and its influences on x,y position. As the projections become more complex, you need to know more about your relationship/orientation in 3D space in order to create a reasonable 2D projection.

上述代码的工作示例可以在此处找到.该示例还包括等距投影函数,可以将其替换为等距投影函数,以查看它如何改变图形的外观.它还执行了一些我没有在此处包含的不同可视化内容,例如绘制阴影"以帮助可视化"实际方向——3D 到 2D 投影的局限性.

A working example of the above code can be found here. The example also includes isometric projection functions that can be swapped out for the dimetric ones to see how that changes the way the graph looks. It also does some different visualization stuff that I didn't include here, like drawing "shadows" to help "visualize" the actual orientation -- the limitations of 3D to 2D projections.

这很复杂,即使是肤浅的讨论也超出了这个 stackoverflow 的范围.我建议您阅读更多 3D 背后的数学知识,网上和印刷形式的资源都很多.一旦您对数学如何工作的基础有了更深入的了解,如果您有关于它的具体实现问题,请返回此处.

It's complicated, and even a superficial discussion is kind of beyond the scope of this stackoverflow. I recommend you read more into the mathematics behind 3D, there are plenty of resources, both online and in print form. Once you have a more solid understanding of the basics of how the math works then return here if you have a specific implementation question about it.

这篇关于如何根据 x、y 和 z 在 3D 矩形中画线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆