我想将图像中表示的 3D 点绘制为 3D 矩形。知道如何在 x、y 和 z 轴上表示这些
这里的投影类型是正交的。
谢谢
好的。让我们看一个简单的例子,说明您要完成什么,以及为什么这是一个如此复杂的问题。
首先,让我们看一些投影函数。您需要一种数学方法来描述如何将 3D(或更高维)点转换为 2D 空间(您的显示器)或投影。
最容易理解的是一个非常简单的二元投影。就像是:
x' = x + z/2;
y' = y + z/4;
这是什么意思?好吧,x'
您是 x 坐标 2D投影吗:对于您在空间中向后移动的每个单位,投影都会将该点向右移动一半的单位。并y'
代表您的 y 坐标的相同投影:对于您在空间中向后移动的每个单位,该投影将将该点向上移动四分之一单位。
所以一个点将[0,0,0]
被投影到一个 2d 点[0,0]
。任意点将[0,0,4]
投影到 的 2d 点[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 画布的简单示例。首先,一些上下文的东西:
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
,以及我们的tx
andty
函数,在这种情况下,我们之前看到的 dimetric 函数。
现在是一个多边形抽屉:
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 投影。
可以在此处找到上述代码的工作示例。该示例还包括等角投影函数,可以将其替换为二角投影函数,以查看它如何改变图形的外观。它还做了一些我在这里没有包含的不同的可视化内容,比如绘制“阴影”以帮助“可视化”实际方向——3D 到 2D 投影的限制。
这很复杂,即使是肤浅的讨论也超出了这个 stackoverflow 的范围。我建议您更多地阅读 3D 背后的数学知识,这里有大量资源,包括在线和印刷形式。一旦您对数学的基本原理有了更深入的了解,如果您有关于它的具体实现问题,请返回此处。
使用您所说的方法不可能做您想做的事情 - 这是因为一个盒子 - 在 3 维旋转时看起来不像您的图表。它也会根据您需要的投影类型而有所不同。但是,您可以开始使用three.js,它是一个用于 Javascript 的 3D 绘图库。
希望这可以帮助。
如何绘制 3D 矩形?发表于:平行四边形 | 更新日期:2012 年 9 月 14 日
绘制 3 - Dimensional Rectangle 意味着我们正在处理与 2 - D 图形不同的图形,后者需要 3 个轴来表示它们。那么,如何绘制 3D 矩形呢?
首先,首先在纸中间画两条线,一条竖线,一条横线,这样它们就代表了英文的“t”字母。这是我们需要绘制的临时使用,稍后将在 3-D 矩形构建完成后将其删除。接下来我们画一个正方形,其每边的尺寸为 1 英寸。正方形在几何上必须是完美的,以便在各个角形成的 90 度角在测量上是精确的。现在从正方形的右上角开始,我们绘制一条线段,该线段将在 45 度角的方向上拉伸到 2 英寸。同样,我们通过从正方形的左上角绘制另一个线段并以 45 度角将其拉伸到 2 英寸长来重复该过程。这两条线段被认为是相对于我们在开始时临时绘制的水平线的对角线。这些线也将彼此平行。接下来我们画一条连接这两条对角线端点的线。
接下来从 2 英寸对角线端点的最右侧开始,画一条 1 英寸的测量线,该线应该垂直于临时水平线。接下来,我们需要将正方形的左下角与我们在第 4 步中绘制的最后 1'' 线的端点连接起来,最后我们得到我们的 3-D 矩形。现在我们可以删除我们最初的“t”。这个 3D 矩形类似于长方体。