2016-05-01 3 views
1

I drew a simple 3-coordinate graph in canvas belowКак вычислить позиции по оси z (холст HTML5)?

Я нарисовал простой трехкоординатный граф в холсте выше;

я определил несколько констант для работы с

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; 

сх и су и CZ все относятся к центру холста. blcx означает, что нижний левый-угол-x, brcy - нижний правый угол-у и т. Д. Я понимаю, что это немного хак-иш, поскольку это первая попытка сделать это, но если вы обнажили меня, это реальная концепция, которую я пытаюсь понять здесь.

, а затем рисовали красные линии, как это:

(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(); 

и получил это:

enter image description here

Но я понял, что я не хватает некоторые фундаментальные математические понятия. Спасибо за любую проницательность, которую вы можете дать! Мой основной вопрос: Как выбрать точку на оси z, заданную на расстоянии от центра?

+0

Что ваш вопрос? Кроме того, пожалуйста, объясните интуицию за вашим кодом. Я не могу этого толковать. Объяснение ваших переменных поможет начать многое. –

+0

Конечно, я обновил оп. Интуиция здесь заключается в том, что я хотел бы определить три оси, x/y/z, и поскольку холст HTML5 не имеет оси z, мне нужно найти способ вычисления точки на оси z, на которую я нарисовал данный на расстоянии от центра. Первое, что я пытался сделать, это нарисовать сетку на плоскости z/y. – pward

+0

Ознакомьтесь с встроенными [искажениями] холста (http://www.rgraph.net/blog/2013/february/an-example-of-the-html5-canvas-transform-function.html) – markE

ответ

2

Трансформаторная 3 измерения в 2-х измерениях

Ось сказать нам, как двигаться

Чтобы найти точку в первой размерности х, движутся вдоль оси х, слева направо. Чтобы найти точку во втором измерении y, вы должны интегрировать как первое, так и второе измерения, таким образом, 1-й x слева направо, после того, как у вас будет то, что затем 2-й по оси y по экрану.

С каждым измерением вы полагаетесь на позиционирование предыдущего измерения. Он также полагается на ось, оси x и y находятся на 90 град друг к другу, но они могут быть на уровне 45 или 120, для поиска двумерных коордов точки не имеет никакого значения. Сначала вдоль оси X, затем Y вдоль оси y.

векторные функции

Так как дисплей только 2D ось может быть представлена ​​в виде 2D векторов. Длина вектора указывает масштаб оси. Таким образом, для оси x, если я определяю ось как вектор 2D (отображающие координаты) (2,0), тогда я говорю, что он идет 2 поперек и 0 вниз для каждого элемента в координате x. Если я хочу быть в координате 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, 
    } 
} 

Итак, давайте определим ось X, что я имел (2,0) усовершенствовались по 2

var xAxis = screenVector(2,0); 

Теперь Топор позиция, скажем, 10

var xPos = 10 

Чтобы найти свое местоположение, нам нужно чтобы получить координаты экрана вдоль оси x. Мы делаем это, умножая xAx на 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 

Теперь, чтобы сделать 2-е измерение мы добавим, что к предыдущему. Давайте определим функцию, чтобы добавить вектор в другой

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); 
} 

Так что теперь позволяет создать ось у

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

и у пос

var posY = 10; 

Так что теперь позволяет сделать это из й

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

Теперь мы добавляем результат s из двух координат

var screenXY = add(screenPosX,screenPosY); 

И мы координата на экране х = 10 и у = 10 (который в этом случае оказывается в пиксельном месте 20 по 20 вниз.

3-й размер

Теперь это не займет много догадаться, что происходит из-за 3-е измерение г. Для х вдоль оси х, то у вдоль оси у, а затем г вдоль оси Z

Таким образом определяют ось г

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

теперь г коорд

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); 

Тогда г

var screenXYZ = add(screenPosXY,screenPosZ); 

и у вас есть, как сделать преобразование из одного набора координат к другой.Это называется преобразованием

Происхождения

Мы недостающие последний бит информации. Происхождение. Именно на этом экране будут показаны координаты 0,0,0 (x, y, z). Это последняя часть преобразования и в экранных координатах (х, у)

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

Из последнего расчета мы получили screenXYZ координаты в экранном пространстве, нам нужно добавить происхождение к нему

screenXYZ = add(screenXYZ ,origin); 

Теперь вы можете нарисовать пиксель в координатах (10,10,10) (x, y, z) из начала координат на экране 2d.

Матрица

Надежда, что помогает, если вы понимаете, что вы только что узнали, как использовать 3D-матрицу преобразования. Он содержит ось x, y, z в виде набора из трех двумерных направлений и координат начала координат. Матрица выполняет те же самые функциональные шаги, только делает это в простом массиве, что делает ее более эффективной и, следуя некоторым матричным правилам, допускает очень сложные преобразования. Например, если вы хотите повернуть, все, что вам нужно сделать, это изменить направление осей, и вы повернули объект. Чтобы изменить масштаб, просто измените длину оси, чтобы переместить объект, просто измените положение начала координат.

+0

Это потрясающий пост. Спасибо! Мне нужно изучить его немного больше и попытаться включить его в игру, прежде чем я решит, что это ответило на мой вопрос! Это первая экспозиция, которую я получил для векторов и векторного пространства, поэтому мне может потребоваться немного времени. – pward

+0

Nice сообщение на deltas/векторов. :-) – markE

+0

«Ось подскажите, как двигаться» - удивительно. – pward

1

Получается, JavaScript JavaScript Math.cos() и Math.sin() очень полезны в этом сценарии. То, как мне приходилось думать об этом, было, как если бы были последовательные концентрические круги с радиусами, начиная с моей длины сегмента сетки и удвоения для каждой последовательности. Оттуда я немного расскажу о том, как найти точку на круге, учитывая степень. Оказывается, круги, как и треугольники, имеют градусы, т. Е. Радиан, а один для направления моего z-индекса - 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(); 
} 

И вот результат:

enter image description here

Смежные вопросы