簡體   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