[英]How to calculate positions on a z-axis
我在畫布上畫了一個簡單的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軸上選擇一個點?
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.