如何计算 z 轴上的位置
How to calculate positions on a z-axis
我在上面canvas画了一个简单的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都是指canvas的中心。 blcx
表示左下角 x,brcy
表示右下角 y,等等。我意识到这有点 hack-ish,因为这是第一次尝试这样做,但是如果你能忍受我的话,我想在这里掌握一个真正的概念。
然后像这样画红线:
(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();
得到这个:
但我意识到我遗漏了一些基本的数学概念。感谢您提供的任何见解!
我的基本问题是:我如何 select z 轴上的一个点距中心一定距离?
将 3 个维度转换为 2 个维度
轴告诉我们如何移动
要在第一维 x 中找到一个点,请沿 x 轴从左到右移动。要在第二维 y 中找到一个点,您必须整合第一维和第二维,因此是从左到右的第一个 x,一旦有了它,然后沿着屏幕下方的 y 轴第二个。
每个维度都依赖于前一个维度的定位。它还依赖于轴,x 轴和 y 轴彼此成 90 度角,但它们可能是 45 度或 120 度,这对找到一个点的二维坐标没有任何影响。首先沿着 X 轴,然后沿着 Y 轴。
向量函数
因为显示只是二维的,所以轴可以表示为二维向量。矢量的长度表示轴的比例。因此,对于 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);
现在 x 位置说 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的第一个维度pos
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 位置
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 坐标
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 坐标 space,我们需要为其添加原点
screenXYZ = add(screenXYZ ,origin);
现在您可以在二维屏幕上从原点在坐标 (10,10,10) (x,y,z) 处绘制像素。
黑客帝国
如果您了解您刚刚学会了如何使用 3D 变换矩阵,希望对您有所帮助。它将 x、y、z 轴作为一组三个 2D 方向,以及原点坐标。矩阵执行完全相同的功能步骤,只是它在一个简单的数组中执行,这使得它更有效,并且遵循一些矩阵规则允许非常复杂的转换。例如,如果你想旋转,你需要做的就是改变轴的方向并且你已经旋转了对象。改变比例只改变轴的长度,移动物体只改变原点的位置。
事实证明,JavaScript 的 Math.cos()
和 Math.sin()
在这种情况下非常有用。我不得不考虑它的方式就好像有连续的同心圆,其半径从我的网格段长度开始,并且每次连续加倍。从那里,我 google 了解了如何在给定度数的圆上找到点。事实证明,圆和三角形一样,有度数,即弧度,而我的 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();
}
结果如下:
我在上面canvas画了一个简单的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都是指canvas的中心。 blcx
表示左下角 x,brcy
表示右下角 y,等等。我意识到这有点 hack-ish,因为这是第一次尝试这样做,但是如果你能忍受我的话,我想在这里掌握一个真正的概念。
然后像这样画红线:
(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();
得到这个:
但我意识到我遗漏了一些基本的数学概念。感谢您提供的任何见解! 我的基本问题是:我如何 select z 轴上的一个点距中心一定距离?
将 3 个维度转换为 2 个维度
轴告诉我们如何移动
要在第一维 x 中找到一个点,请沿 x 轴从左到右移动。要在第二维 y 中找到一个点,您必须整合第一维和第二维,因此是从左到右的第一个 x,一旦有了它,然后沿着屏幕下方的 y 轴第二个。
每个维度都依赖于前一个维度的定位。它还依赖于轴,x 轴和 y 轴彼此成 90 度角,但它们可能是 45 度或 120 度,这对找到一个点的二维坐标没有任何影响。首先沿着 X 轴,然后沿着 Y 轴。
向量函数
因为显示只是二维的,所以轴可以表示为二维向量。矢量的长度表示轴的比例。因此,对于 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);
现在 x 位置说 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的第一个维度pos
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 位置
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 坐标
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 坐标 space,我们需要为其添加原点
screenXYZ = add(screenXYZ ,origin);
现在您可以在二维屏幕上从原点在坐标 (10,10,10) (x,y,z) 处绘制像素。
黑客帝国
如果您了解您刚刚学会了如何使用 3D 变换矩阵,希望对您有所帮助。它将 x、y、z 轴作为一组三个 2D 方向,以及原点坐标。矩阵执行完全相同的功能步骤,只是它在一个简单的数组中执行,这使得它更有效,并且遵循一些矩阵规则允许非常复杂的转换。例如,如果你想旋转,你需要做的就是改变轴的方向并且你已经旋转了对象。改变比例只改变轴的长度,移动物体只改变原点的位置。
事实证明,JavaScript 的 Math.cos()
和 Math.sin()
在这种情况下非常有用。我不得不考虑它的方式就好像有连续的同心圆,其半径从我的网格段长度开始,并且每次连续加倍。从那里,我 google 了解了如何在给定度数的圆上找到点。事实证明,圆和三角形一样,有度数,即弧度,而我的 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();
}
结果如下: