我想将图像中表示的3D点绘制为3D矩形。我知道如何在x,y和z轴上表示这些
此处投影类型为拼写。
由于
答案 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
,以及我们的tx
和ty
函数,在本例中我们是我们之前看到的二次函数
现在是一个多边形抽屉:
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”。这个三维矩形类似于长方体。