繁体   English   中英

如何计算z轴上的位置

[英]How to calculate positions on a z-axis

我在下面的画布中绘制了一个简单的3坐标图

我在画布上画了一个简单的3坐标图;

我定义了一些常量来处理

var width = window.innerWidth * 0.5 , height = window.innerWidth * 0.5;
var cx = width / 2, cy = height / 2, cz = height / 2, blcx = 0, blcy = height, brcz = height, brcx = width, brcy = height;

var ySegment = height / 30;
var xSegment = width / 30; 
var xSegmentRatio = xSegment / width; 
var ySegmentRatio = ySegment / height;

cx和cy和cz都是指画布的中心。 blcx意味着左下角-x, brcy是右下角-y等。我意识到这有点黑客,因为这是第一次尝试这样做,但如果你忍受我,那里是一个我想在这里抓住的真实概念。

然后画出这样的红线:

(function() {
    var gridCx   = cx,       gridCy   = cy,        gridCz = cz;
    var gridBlCx = blcx,     gridBlCy = brcy;
    for (var i = cx; i < width; i++) {
        gridCx += xSegment;
        gridBlCx += ySegment;
        gridCzx -= gridCzx * (xSegmentRatio / ySegmentRatio);
        ctx.beginPath();
        ctx.moveTo(gridCx, cy);
        ctx.lineTo(gridBlCx, height);
        ctx.strokeStyle="#FF0000";
        ctx.stroke();
    }
})();

我试过这个:

gridCzx -= gridCzx * xSegmentRatio;
gridCzy += gridCzy * ySegmentRatio;
ctx.beginPath();
ctx.moveTo(gridCzx, gridCzy);
ctx.lineTo(width, gridCzy);
ctx.strokeStyle = "#ff0000";
ctx.stroke();

得到了这个:

在此输入图像描述

但我意识到我缺少一些基本的数学概念。 感谢您提供的任何见解! 我的基本问题是: 如何在距离中心一定距离的z轴上选择一个点?

将3个维度转换为2个维度

Axis告诉我们如何移动

要在第一维x中找到一个点,请沿x轴从左向右移动。 要在第二个维度y中找到一个点,您必须整合第一个和第二个维度,从而从左到右依次为第一个x,然后在屏幕下沿y轴进行第二个x。

每个维度都依赖于前一维度的定位。 它也依赖于轴,x和y轴彼此成90度,但它们可以是45或120,找到一个点的2D坐标没有任何区别。 首先沿X轴,然后沿y轴Y.

矢量函数

因为显示器仅为2D,所以轴可以表示为2D矢量。 矢量的长度表示轴的比例。 因此,对于x轴,如果我将轴定义为2D(显示坐标)向量(2,0),那么我说它对于x坐标中的每个单位为2和0。 如果我想要在x坐标10处,我将它乘以轴以获得屏幕位置。

因此对代码......

function screenCoord(x,y){  // creates a coordinate in screen space
                            // screen space is always in pixels
                            // screen space always has the origin (0,0) at the top left
    return {
       x : x,
       y : y,
    }
}

function screenVector(x,y){ // a vector in screen space it points in a direction
                            // and its is in pixels 
    return {                // basically identical to the last function 
       x : x,
       y : y,
    }
}

所以让我们定义我有(2,0)按比例缩放2的X轴

var xAxis = screenVector(2,0);

现在斧头位置说10

var xPos = 10

要找到它的位置,我们需要获得沿x轴的屏幕坐标。 我们通过将xAxis乘以xPos来实现。 为了更容易,我们可以创建一个向量乘法函数

function multiply(vector, value){
     var x = vector.x * value; // multiply the vector x by value
     var y = vector.y * value; // multiply the vector y by value
     return screenCoord(x,y)
}

现在找到xPos的第一个维度位置

var screenPos = multiply(xAxis, xPos); // returns the screen position of x = 10

现在做第二个维度,我们将其添加到前一个维度。 让我们定义一个向另一个添加向量的函数

function add(vector1, vector2){ // adds two vectors returning a new one
     var x = vector1.x + vector2.x;
     var y = vector1.y + vector2.y;
     return screenCoord(x,y);
}

所以现在让我们创建y轴

var yAxis = new screenVector(0,2); // y goes down the screen and has no x change

和y pos

var posY = 10;

所以现在让我们从x做

var screenPosX = multiply(xAxis,posX); // get the x position on the screen
var screenPosY = multiply(yAxis,posY); // get the y position on the screen

现在我们添加两个坐标的结果

var screenXY = add(screenPosX,screenPosY);

我们在x = 10和y = 10的屏幕上有一个坐标(在这种情况下,它在20英尺处的像素位置20处。

第三个维度

现在猜测第3个z维度会发生什么并不需要太多。 对于沿x轴的x,沿y轴为y,然后沿z轴为z

因此定义z轴

var yAxis = new screenVector(1,-1); // z axis along the diagonal from bottom left to top right

现在是z coord

var posZ = 10;

因此,要找到我们的3d位置,x沿其轴,然后沿其添加y,然后沿其轴添加z

var screenPosX = multiply(xAxis,posX); // get the x position on the screen
var screenPosY = multiply(yAxis,posY); // get the y position on the screen
var screenPosZ = multiply(zAxis,posZ); // get the z position on the screen

需要将它们加在一起

var screenXY = add(screenPosX,screenPosY);

然后是z

var screenXYZ = add(screenPosXY,screenPosZ);

在那里你有如何从一组坐标转换到另一组坐标。 它被称为变换

起源

我们遗漏了最后一点信息。 起源。 这是屏幕上的坐标0,0,0(x,y,z)。 它是变换的最后一部分,是屏幕坐标(x,y)

var origin = screenCoords(100,500); // set the origin at 100 pixels across 500 down

从上次计算中我们得到了屏幕空间中的screenXYZ坐标,我们需要将原点添加到它

screenXYZ = add(screenXYZ ,origin);

现在,您可以在2d屏幕上从原点绘制坐标(10,10,10)(x,y,z)处的像素。

矩阵

希望这有帮助,如果您了解您刚刚学会了如何使用3D转换矩阵。 它将x,y,z轴保持为三个2D方向的集合,以及原点的坐标。 矩阵执行完全相同的功能步骤,只是它在一个简单的数组中使它更有效,并遵循一些矩阵规则允许非常复杂的变换。 例如,如果要旋转,您需要做的就是更改轴的方向并旋转对象。 要更改比例只需更改轴的长度,移动对象只需更改原点的位置即可。

事实证明,JavaScript的Math.cos()Math.sin()在这种情况下非常有用。 我不得不考虑它的方式就好像有连续的同心圆,半径从我的网格段长度开始,每次连续加倍。 从那里,我谷歌一些关于如何在给定学位的圆上找到点。 事实证明,圆形,如三角形,有度,即弧度,而我的z-index方向的圆是5PI / 4。 因此,我的函数看起来像这样:

for (var i = 0; i < zDistance; i++) {
    var r = xSegment * i;
    ctx.beginPath();
    ctx.arc(cx, cy, r, 0, 2 * Math.PI);
    ctx.strokeStyle="white";
    ctx.stroke();
    var zRadian = {
        divided: function() {
            return 5 * Math.PI
        }, 
        divisor: function() {
            return 4;
        }
    }
    var zRadian = zRadian.divided() / zRadian.divisor();
    var x = cx + r * Math.cos(zRadian);
    var y = cy - r * Math.sin(zRadian);
    ctx.beginPath();
    ctx.fillText('(' + x + ', ' + y + ')', x, y);
    ctx.stroke();
}

这是结果:

在此输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM