假设您有一个矩形,并且想要旋转它。在开始旋转之前,右上角是 3.0、9.0。让我们在单位圆上从 12 点顺时针方向选择一个点。
圆圈上的位置是 0.50 和 0.87
rotatedX = a_position.x * u_rotation.y + a_position.y * u_rotation.x;
rotatedY = a_position.y * u_rotation.y - a_position.x * u_rotation.x;
顺时针 60 度也一样
3.0 * 0.50 + 9.0 * 0.87 = 9.3
9.0 * 0.50 - 3.0 * 0.87 = 1.9
您可以看到,当我们将该点顺时针向右旋转时,X 值变大而 Y 值变小。如果我们继续超过 90 度,X 会再次开始变小,而 Y 会开始变大。这种模式给了我们旋转。
单位圆上的点还有另一个名称。它们被称为正弦和余弦。因此,对于任何给定的角度,我们都可以像这样查找正弦和余弦。
-----------------------------------------扩展理解 ----------------------------------------
"use strict";
function main() {
// Get A WebGL context
/** @type {HTMLCanvasElement} */
var canvas = document.querySelector("#canvas");
var gl = canvas.getContext("webgl");
if (!gl) {
return;
}
// setup GLSL program
var program = webglUtils.createProgramFromScripts(gl, ["vertex-shader-2d", "fragment-shader-2d"]);
// look up where the vertex data needs to go.
var positionLocation = gl.getAttribLocation(program, "a_position");
// lookup uniforms
var resolutionLocation = gl.getUniformLocation(program, "u_resolution");
var colorLocation = gl.getUniformLocation(program, "u_color");
var translationLocation = gl.getUniformLocation(program, "u_translation");
var rotationLocation = gl.getUniformLocation(program, "u_rotation");
// Create a buffer to put positions in
var positionBuffer = gl.createBuffer();
// Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// Put geometry data into buffer
setGeometry(gl);
var translation = [100, 150];
var rotation = [0, 1];
var color = [Math.random(), Math.random(), Math.random(), 1];
drawScene();
// Setup a ui.
webglLessonsUI.setupSlider("#x", {value: translation[0], slide: updatePosition(0), max: gl.canvas.width });
webglLessonsUI.setupSlider("#y", {value: translation[1], slide: updatePosition(1), max: gl.canvas.height});
$("#rotation").gmanUnitCircle({
width: 200,
height: 200,
value: 0,
slide: function(e,u) {
rotation[0] = u.x;
rotation[1] = u.y;
drawScene();
}
});
function updatePosition(index) {
return function(event, ui) {
translation[index] = ui.value;
drawScene();
};
}
// Draw the scene.
function drawScene() {
webglUtils.resizeCanvasToDisplaySize(gl.canvas);
// Tell WebGL how to convert from clip space to pixels
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
// Clear the canvas.
gl.clear(gl.COLOR_BUFFER_BIT);
// Tell it to use our program (pair of shaders)
gl.useProgram(program);
// Turn on the attribute
gl.enableVertexAttribArray(positionLocation);
// Bind the position buffer.
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER)
var size = 2; // 2 components per iteration
var type = gl.FLOAT; // the data is 32bit floats
var normalize = false; // don't normalize the data
var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
var offset = 0; // start at the beginning of the buffer
gl.vertexAttribPointer(
positionLocation, size, type, normalize, stride, offset);
// set the resolution
gl.uniform2f(resolutionLocation, gl.canvas.width, gl.canvas.height);
// set the color
gl.uniform4fv(colorLocation, color);
// Set the translation.
gl.uniform2fv(translationLocation, translation);
// Set the rotation.
gl.uniform2fv(rotationLocation, rotation);
// Draw the geometry.
var primitiveType = gl.TRIANGLES;
var offset = 0;
var count = 18; // 6 triangles in the 'F', 3 points per triangle
gl.drawArrays(primitiveType, offset, count);
}
}
// Fill the buffer with the values that define a letter 'F'.
function setGeometry(gl) {
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([
// left column
0, 0,
30, 0,
0, 150,
0, 150,
30, 0,
30, 150,
// top rung
30, 0,
100, 0,
30, 30,
30, 30,
100, 0,
100, 30,
// middle rung
30, 60,
67, 60,
30, 90,
30, 90,
67, 60,
67, 90,
]),
gl.STATIC_DRAW);
}
$(function(){
main();
});
--------------------------------------扩展阅读:三角函数----------------------------------
感谢这位台湾老师,让我的三角函数在班中无敌手。数学入门基础教程中华科技大学公开课李柏坚教授_哔哩哔哩_bilibili
什么是弧度?
弧度是用于圆、旋转和角度的测量单位。就像我们可以用英寸、码、米等来测量距离一样,我们可以用度或弧度来测量角度。
您可能知道使用公制测量的数学比使用英制测量的数学更容易。从英寸到英尺,我们除以 12。从英寸到码,我们除以 36。我不了解你,但我无法在脑海中除以 36。使用公制就容易多了。从毫米到厘米,我们乘以 10。从毫米到米,我们乘以 1000。我可以在脑海中乘以 1000。
弧度与度数相似。学位使数学变得困难。弧度使数学变得容易。一个圆有 360 度,但只有 2π 弧度。所以一整圈是 2π 弧度。半圈是 1π 弧度。1/4 转,即 90 度是 1/2π 弧度。因此,如果您想将某些东西旋转 90 度,只需使用Math.PI * 0.5
. 如果您想将其旋转 45 度,请使用Math.PI * 0.25
等。
如果您开始以弧度思考,几乎所有涉及角度、圆或旋转的数学运算都非常简单。所以试试看。使用弧度,而不是度数,除非在 UI 显示中。
获取坐标----------------------
function click(ev, gl, canvas, a_Position, u_FragColor) {
var x = ev.clientX; // x coordinate of a mouse pointer
var y = ev.clientY; // y coordinate of a mouse pointer
var rect = ev.target.getBoundingClientRect();
x = ((x - rect.left) - canvas.width/2)/(canvas.width/2);
y = (canvas.height/2 - (y - rect.top))/(canvas.height/2);
// Store the coordinates to g_points array
g_points.push([x, y]);
// Store the coordinates to g_points array
if (x >= 0.0 && y >= 0.0) { // First quadrant
g_colors.push([1.0, 0.0, 0.0, 1.0]); // Red
} else if (x < 0.0 && y < 0.0) { // Third quadrant
g_colors.push([0.0, 1.0, 0.0, 1.0]); // Green
} else { // Others
g_colors.push([1.0, 1.0, 1.0, 1.0]); // White
}
// Clear <canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
var len = g_points.length;
for(var i = 0; i < len; i++) {
var xy = g_points[i];
var rgba = g_colors[i];
// Pass the position of a point to a_Position variable
gl.vertexAttrib3f(a_Position, xy[0], xy[1], 0.0);
// Pass the color of a point to u_FragColor variable
gl.uniform4f(u_FragColor, rgba[0], rgba[1], rgba[2], rgba[3]);
// Draw
gl.drawArrays(gl.POINTS, 0, 1);
}
}
webgl单点绘制-----------------------------------------
var g_points = []; // The array for the position of a mouse press
function click(ev, gl, canvas, a_Position) {
var x = ev.clientX; // x coordinate of a mouse pointer
var y = ev.clientY; // y coordinate of a mouse pointer
var rect = ev.target.getBoundingClientRect() ;
x = ((x - rect.left) - canvas.width/2)/(canvas.width/2);
y = (canvas.height/2 - (y - rect.top))/(canvas.height/2);
// Store the coordinates to g_points array
g_points.push(x); g_points.push(y);
// Clear <canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
var len = g_points.length;
for(var i = 0; i < len; i += 2) {
// Pass the position of a point to a_Position variable
gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0);
// Draw
gl.drawArrays(gl.POINTS, 0, 1);
}
}