webGL :沿 Y 轴围绕一个点旋转矩形 [英] webGL : Rotation of a rectangle about a point along Y axis

查看:37
本文介绍了webGL :沿 Y 轴围绕一个点旋转矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个有 4 个顶点的矩形 (x1,y1), (x2,y2) (x3,y3) 和 (x4,y4).这些顶点按顺时针顺序排列.矩形的方向像 (x1,y1) 是最左上角,(x3,y3) 是最右下角.

Assume I have a rectangle having 4 vertices (x1,y1), (x2,y2) (x3,y3) and (x4,y4). These vertices are in clockwise order.The rectangle is oriented like (x1,y1) is the top most left side corner and (x3,y3) is the bottom most Right Corner.

现在我想围绕包括 (x2,y2) 和 (x3,y3) 的边 i,e 之一旋转矩形.我想通过旋转两个顶点 (x1,y1) 和 (x4,y4).

Now i want to rotate the rectangle around one of the edge i,e along the edge that includes (x2,y2) and (x3,y3).I want to achieve this effect in Shaders by rotating two Vertices (x1,y1) and (x4,y4).

我的问题是围绕某个点以角度 Theta 旋转点 (x1,y1) 的公式是什么.

My question is What is the formula for Rotating a point (x1,y1) with an angle Theta around a certain point.

我搜索了较旧的论坛并找到了一些相关信息https://stackoverflow.com/a/3162657/1804924

I have searched the older forums and found some relevant information https://stackoverflow.com/a/3162657/1804924

我的问题是我可以按原样使用方程吗..因为它就像绕 Y 轴旋转一样.

My question is can i use the equation as it is.. because it is like rotation about Y-axis.

推荐答案

这里有一系列关于 2D 旋转数学的文章

There's a series of articles that goes over the math for 2D rotations here

https://webglfundamentals.org/webgl/lessons/webgl-2d-rotation.html

它从简单开始,然后构建到 2D 矩阵数学,这是做这些事情的最常用方法

It's starts simple and builds up to 2D matrix math which is the most common way to do this stuff

一旦您使矩阵工作,您将生成一个矩阵来转换矩形,以便 X2,y2 和 x3,y3 之间的点位于 0,0.然后生成一个旋转的矩阵.然后另一个翻译回来.将它们全部相乘,您将得到一个可以完成所有工作的矩阵.

Once you have the matrices working you'd generate a matrix that translates the rectangle so that the point between X2,y2 and x3,y3 is at 0,0. Then generate a matrix that rotates. Then another to translate back. Multiply them all together and you'll get one matrix that does the entire thing.

// Compute the matrices
var rotatePointX = (x2 + x3) / 2;
var rotatePointY = (y2 + y3) / 2;

var moveToRotationPointMatrix = makeTranslation(-rotatePointX, -rotatePointY);
var rotationMatrix = makeRotation(angleInRadians);
var moveBackMatrix = makeTranslation(rotatePointX, rotatePointY);

// Multiply the matrices.
var matrix = matrixMultiply(moveToRotationPointMatrix, rotationMatrix);
matrix = matrixMultiply(matrix, moveBackMatrix);
...

现在使用该矩阵

这是一个例子.它围绕右边缘的中心旋转.

Here's an example. It's rotating halfway between around the center of the right edge.

function main() {
  // Get A WebGL context
  var canvas = document.getElementById("canvas");
  var gl = canvas.getContext("webgl");
  if (!gl) {
    return;
  }

  // setup GLSL program
  program = twgl.createProgramFromScripts(gl, ["2d-vertex-shader", "2d-fragment-shader"]);
  gl.useProgram(program);

  // look up where the vertex data needs to go.
  var positionLocation = gl.getAttribLocation(program, "a_position");

  // lookup uniforms
  var colorLocation = gl.getUniformLocation(program, "u_color");
  var matrixLocation = gl.getUniformLocation(program, "u_matrix");

  // Create a buffer.
  var buffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
  gl.enableVertexAttribArray(positionLocation);
  gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);

  // Set Geometry.
  setGeometry(gl);

  // Set a random color.
  gl.uniform4f(colorLocation, Math.random(), Math.random(), Math.random(), 1);

  var translation = [100, 150];
  var angleInRadians = 0;
  var scale = [1, 1];
    
  // Draw the scene.
  function drawScene() {
    angleInRadians += 0.01;
    // Clear the canvas.
    gl.clear(gl.COLOR_BUFFER_BIT);

    // Compute the matrices
    var projectionMatrix = make2DProjection(canvas.width, canvas.height);

    var x2 = 130;
    var x3 = 130;
    var y2 =  30;
    var y3 = 150;
      
    var rotatePointX = (x2 + x3) / 2;
    var rotatePointY = (y2 + y3) / 2;
      
    var moveToRotationPointMatrix = makeTranslation(-rotatePointX, -rotatePointY);
    var rotationMatrix = makeRotation(angleInRadians);
    var moveBackMatrix = makeTranslation(rotatePointX, rotatePointY);

    // Multiply the matrices.
    var matrix = matrixMultiply(moveToRotationPointMatrix, rotationMatrix);
    matrix = matrixMultiply(matrix, moveBackMatrix);
    matrix = matrixMultiply(matrix, projectionMatrix);
    
    // Set the matrix.
    gl.uniformMatrix3fv(matrixLocation, false, matrix);

    // Draw the geometry.
    gl.drawArrays(gl.TRIANGLES, 0, 6);
      
    requestAnimationFrame(drawScene);
  }
  drawScene();
}

function make2DProjection(width, height) {
  // Note: This matrix flips the Y axis so 0 is at the top.
  return [
    2 / width, 0, 0,
    0, -2 / height, 0,
    -1, 1, 1
  ];
}

function makeTranslation(tx, ty) {
  return [
    1, 0, 0,
    0, 1, 0,
    tx, ty, 1
  ];
}

function makeRotation(angleInRadians) {
  var c = Math.cos(angleInRadians);
  var s = Math.sin(angleInRadians);
  return [
    c,-s, 0,
    s, c, 0,
    0, 0, 1
  ];
}

function makeScale(sx, sy) {
  return [
    sx, 0, 0,
    0, sy, 0,
    0, 0, 1
  ];
}

function matrixMultiply(a, b) {
  var a00 = a[0*3+0];
  var a01 = a[0*3+1];
  var a02 = a[0*3+2];
  var a10 = a[1*3+0];
  var a11 = a[1*3+1];
  var a12 = a[1*3+2];
  var a20 = a[2*3+0];
  var a21 = a[2*3+1];
  var a22 = a[2*3+2];
  var b00 = b[0*3+0];
  var b01 = b[0*3+1];
  var b02 = b[0*3+2];
  var b10 = b[1*3+0];
  var b11 = b[1*3+1];
  var b12 = b[1*3+2];
  var b20 = b[2*3+0];
  var b21 = b[2*3+1];
  var b22 = b[2*3+2];
  return [a00 * b00 + a01 * b10 + a02 * b20,
          a00 * b01 + a01 * b11 + a02 * b21,
          a00 * b02 + a01 * b12 + a02 * b22,
          a10 * b00 + a11 * b10 + a12 * b20,
          a10 * b01 + a11 * b11 + a12 * b21,
          a10 * b02 + a11 * b12 + a12 * b22,
          a20 * b00 + a21 * b10 + a22 * b20,
          a20 * b01 + a21 * b11 + a22 * b21,
          a20 * b02 + a21 * b12 + a22 * b22];
}

// Fill the buffer with the values that make a rect.
function setGeometry(gl) {
  gl.bufferData(
      gl.ARRAY_BUFFER,
      new Float32Array([
           10,  30,
          130,  30,
           10, 150,
           10, 150,
          130,  30,
          130, 150]),
      gl.STATIC_DRAW);
}
main();

canvas {
    border: 1px solid black;
}

<script src="https://twgljs.org/dist/3.x/twgl.min.js"></script>
<!-- vertex shader -->
<script id="2d-vertex-shader" type="x-shader/x-vertex">
attribute vec2 a_position;

uniform mat3 u_matrix;

void main() {
  // Multiply the position by the matrix.
  gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy, 0, 1);
}
</script>
<!-- fragment shader -->
<script id="2d-fragment-shader" type="x-shader/x-fragment">
precision mediump float;

uniform vec4 u_color;

void main() {
   gl_FragColor = u_color;
}
</script>
<canvas id="canvas" width="400" height="300"></canvas>

这篇关于webGL :沿 Y 轴围绕一个点旋转矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆