javascript - 旋转机械臂
问题描述
目标:以下代码的目标是制作一个移动的机器人手臂,它具有三层(上、下和中),所有这些都连接到底座上。给出了 4 个滑块,它们可以独立移动每个部分,除了将移动所有手臂的底座。
问题:我遇到的问题是,当我尝试运行此代码时,屏幕上没有任何视觉效果,控制台中也没有错误,我找不到问题的原因。我还附上了输出的图片。
解决方法:还没找到。
var NumVertices = 36;
var points = [];
var colors = [];
var vertices = [
vec4( -0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, -0.5, -0.5, 1.0 ),
vec4( -0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, -0.5, -0.5, 1.0 )
];
var vertexColors = [
vec4( 0.0, 0.0, 0.0, 1.0 ), // black
vec4( 1.0, 0.0, 0.0, 1.0 ), // red
vec4( 1.0, 1.0, 0.0, 1.0 ), // yellow
vec4( 0.0, 1.0, 0.0, 1.0 ), // green
vec4( 0.0, 0.0, 1.0, 1.0 ), // blue
vec4( 1.0, 0.0, 1.0, 1.0 ), // magenta
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
vec4( 0.0, 1.0, 1.0, 1.0 ) // cyan
];
var BASE_HEIGHT = 2.0;
var BASE_WIDTH = 5.0;
var LOWER_ARM_HEIGHT = 5.0;
var LOWER_ARM_WIDTH = 0.5;
var UPPER_ARM_HEIGHT = 5.0;
var UPPER_ARM_WIDTH = 0.5;
var MIDDLE_ARM_HEIGHT = 5.0;
var MIDDLE_ARM_WIDTH = 0.5;
var modelViewMatrix, projectionMatrix;
var Base = 0;
var LowerArm = 1;
var UpperArm = 2;
var MiddleArm = 3;
var theta= [ 0, 0, 0, 0];
var angle = 0;
var modelViewMatrixLoc;
var vBuffer, cBuffer;
function quad( a, b, c, d ) {
colors.push(vertexColors[a]);
points.push(vertices[a]);
colors.push(vertexColors[a]);
points.push(vertices[b]);
colors.push(vertexColors[a]);
points.push(vertices[c]);
colors.push(vertexColors[a]);
points.push(vertices[a]);
colors.push(vertexColors[a]);
points.push(vertices[c]);
colors.push(vertexColors[a]);
points.push(vertices[d]);
}
function colorCube() {
quad( 1, 0, 3, 2 );
quad( 2, 3, 7, 6 );
quad( 3, 0, 4, 7 );
quad( 6, 5, 1, 2 );
quad( 4, 5, 6, 7 );
quad( 5, 4, 0, 1 );
}
function scale4(a, b, c, d) {
var result = mat4();
result[0][0] = a;
result[1][1] = b;
result[2][2] = c;
result[3][3] = d;
return result;
}
window.onload = function init() {
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
gl.enable( gl.DEPTH_TEST );
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
colorCube();
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
cBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );
gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vColor );
document.getElementById("slider1").onchange = function(event) {
theta[0] = event.target.value;
};
document.getElementById("slider2").onchange = function(event) {
theta[1] = event.target.value;
};
document.getElementById("slider3").onchange = function(event) {
theta[2] = event.target.value;
};
document.getElementById("slider4").onchange = function(event) {
theta[3] = event.target.value;
};
modelViewMatrixLoc = gl.getUniformLocation(program, "modelViewMatrix");
projectionMatrix = ortho(-10, 10, -10, 10, -10, 10);
gl.uniformMatrix4fv( gl.getUniformLocation(program, "projectionMatrix"), false, flatten(projectionMatrix) );
render();
}
function base() {
var s = scale4(BASE_WIDTH, BASE_HEIGHT, BASE_WIDTH);
var instanceMatrix = mult( translate( 0.0, 0.5 * BASE_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function upperArm() {
var s = scale4(UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH);
var instanceMatrix = mult(translate( 0.0, 0.5 * UPPER_ARM_HEIGHT, 0.0 ),s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function lowerArm()
{
var s = scale4(LOWER_ARM_WIDTH, LOWER_ARM_HEIGHT, LOWER_ARM_WIDTH);
var instanceMatrix = mult( translate( 0.0, 0.5 * LOWER_ARM_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function middleArm()
{
var s = scale4(MIDDLE_ARM_WIDTH, MIDDLE_ARM_HEIGHT, MIDDLE_ARM_WIDTH);
var instanceMatrix = mult( translate( 0.0, 0.5 * MIDDLE_ARM_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
var render = function() {
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
modelViewMatrix = rotate(theta[Base], 0, 1, 0 );
base();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, BASE_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[LowerArm], 0, 0, 1 ));
lowerArm();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, LOWER_ARM_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[UpperArm], 0, 0, 1) );
upperArm();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, UPPER_ARM_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[MiddleArm], 0, 0, 1) );
middleArm();
requestAnimFrame(render);
}
<html>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
varying vec4 fColor;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
void main()
{
fColor = vColor;
gl_Position = projectionMatrix * modelViewMatrix * vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;
void main()
{
gl_FragColor = fColor;
}
</script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script type="text/javascript"src="https://esangel.github.io/WebGL/Common/MV.js"></script>
<script type="text/javascript" src="robotArm.js"></script>
<div id="slider1">
body angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider2">
lower arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider4">
middle arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider3">
upper arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<body>
<canvas id="gl-canvas" width="512"" height="512"
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
解决方案
我做的第一件事是添加webgl-lint
<script src="https://greggman.github.io/webgl-lint/webgl-lint.js" crossorigin></script>
那立即得到了错误
Uncaught Error: https://greggman.github.io/webgl-lint/webgl-lint.js:2843:
error in
uniformMatrix4fv(WebGLUniformLocation("modelViewMatrix"),
false,
[5, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 0, NaN, NaN, NaN, NaN]): element 12 of argument 2 is NaN
: trying to set uniform 'modelViewMatrix'
at reportError (webgl-lint.js:2163)
at reportFunctionError (webgl-lint.js:2924)
at checkArrayForUniformImpl (webgl-lint.js:2843)
at webgl-lint.js:2869
at checkArgs (webgl-lint.js:2972)
at WebGLRenderingContext.ctx.<computed> [as uniformMatrix4fv] (webgl-lint.js:3016)
at base (js:230)
at render (js:267)
at init (js:223)
查看您的代码,问题是rotate
不需要 4 个参数,它需要 2 个参数,一个角度和一个轴
r = rotate(angle, x, y, z); // BAD!
r = rotate(angle, [x, y, z]); // Good
修复 webgl-lint 打印了一个新错误。问题是scale4
需要 4 个参数。
s = scale4(x, y, z); // BAD!
s = scale4(x, y, z, w); // good
你想通过1
w。
那个固定的渲染。至于您可能想要render
在每个onchange
函数中调用的滑块。您可能还想使用oninput
而不是onchange
var NumVertices = 36;
var points = [];
var colors = [];
var vertices = [
vec4( -0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, -0.5, -0.5, 1.0 ),
vec4( -0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, -0.5, -0.5, 1.0 )
];
var vertexColors = [
vec4( 0.0, 0.0, 0.0, 1.0 ), // black
vec4( 1.0, 0.0, 0.0, 1.0 ), // red
vec4( 1.0, 1.0, 0.0, 1.0 ), // yellow
vec4( 0.0, 1.0, 0.0, 1.0 ), // green
vec4( 0.0, 0.0, 1.0, 1.0 ), // blue
vec4( 1.0, 0.0, 1.0, 1.0 ), // magenta
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
vec4( 0.0, 1.0, 1.0, 1.0 ) // cyan
];
var BASE_HEIGHT = 2.0;
var BASE_WIDTH = 5.0;
var LOWER_ARM_HEIGHT = 5.0;
var LOWER_ARM_WIDTH = 0.5;
var UPPER_ARM_HEIGHT = 5.0;
var UPPER_ARM_WIDTH = 0.5;
var MIDDLE_ARM_HEIGHT = 5.0;
var MIDDLE_ARM_WIDTH = 0.5;
var modelViewMatrix, projectionMatrix;
var Base = 0;
var LowerArm = 1;
var UpperArm = 2;
var MiddleArm = 3;
var theta= [ 0, 0, 0, 0];
var angle = 0;
var modelViewMatrixLoc;
var vBuffer, cBuffer;
function quad( a, b, c, d ) {
colors.push(vertexColors[a]);
points.push(vertices[a]);
colors.push(vertexColors[a]);
points.push(vertices[b]);
colors.push(vertexColors[a]);
points.push(vertices[c]);
colors.push(vertexColors[a]);
points.push(vertices[a]);
colors.push(vertexColors[a]);
points.push(vertices[c]);
colors.push(vertexColors[a]);
points.push(vertices[d]);
}
function colorCube() {
quad( 1, 0, 3, 2 );
quad( 2, 3, 7, 6 );
quad( 3, 0, 4, 7 );
quad( 6, 5, 1, 2 );
quad( 4, 5, 6, 7 );
quad( 5, 4, 0, 1 );
}
function scale4(a, b, c, d) {
var result = mat4();
result[0][0] = a;
result[1][1] = b;
result[2][2] = c;
result[3][3] = d;
return result;
}
window.onload = function init() {
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
gl.enable( gl.DEPTH_TEST );
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
colorCube();
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
cBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );
gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vColor );
document.getElementById("slider1").oninput = function(event) {
theta[0] = event.target.value;
render();
};
document.getElementById("slider2").oninput = function(event) {
theta[1] = event.target.value;
render();
};
document.getElementById("slider3").oninput = function(event) {
theta[2] = event.target.value;
render();
};
document.getElementById("slider4").oninput = function(event) {
theta[3] = event.target.value;
render();
};
modelViewMatrixLoc = gl.getUniformLocation(program, "modelViewMatrix");
projectionMatrix = ortho(-10, 10, -10, 10, -10, 10);
gl.uniformMatrix4fv( gl.getUniformLocation(program, "projectionMatrix"), false, flatten(projectionMatrix) );
render();
}
function base() {
var s = scale4(BASE_WIDTH, BASE_HEIGHT, BASE_WIDTH, 1);
var instanceMatrix = mult( translate( 0.0, 0.5 * BASE_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function upperArm() {
var s = scale4(UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH, 1);
var instanceMatrix = mult(translate( 0.0, 0.5 * UPPER_ARM_HEIGHT, 0.0 ),s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function lowerArm()
{
var s = scale4(LOWER_ARM_WIDTH, LOWER_ARM_HEIGHT, LOWER_ARM_WIDTH, 1);
var instanceMatrix = mult( translate( 0.0, 0.5 * LOWER_ARM_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function middleArm()
{
var s = scale4(MIDDLE_ARM_WIDTH, MIDDLE_ARM_HEIGHT, MIDDLE_ARM_WIDTH, 1);
var instanceMatrix = mult( translate( 0.0, 0.5 * MIDDLE_ARM_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
var render = function() {
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
modelViewMatrix = rotate(theta[Base], [0, 1, 0]);
base();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, BASE_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[LowerArm], [0, 0, 1] ));
lowerArm();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, LOWER_ARM_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[UpperArm], [0, 0, 1]) );
upperArm();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, UPPER_ARM_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[MiddleArm], [0, 0, 1]) );
middleArm();
requestAnimFrame(render);
}
<html>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
varying vec4 fColor;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
void main()
{
fColor = vColor;
gl_Position = projectionMatrix * modelViewMatrix * vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;
void main()
{
gl_FragColor = fColor;
}
</script>
<script src="https://greggman.github.io/webgl-lint/webgl-lint.js" crossorigin></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script type="text/javascript"src="https://esangel.github.io/WebGL/Common/MV.js"></script>
<script type="text/javascript" src="robotArm.js"></script>
<div id="slider1">
body angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider2">
lower arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider4">
middle arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider3">
upper arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<body>
<canvas id="gl-canvas" width="512"" height="512"
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
推荐阅读
- unix - Unix sed 命令 - 提取两个斜杠之间的文本
- python - 基于包含分隔符的现有 df 列创建 df 列
- html - 子元素的平滑悬停过渡
- mapbox - 用于 geojson 集合的 Mapbox 过滤,以根据值是否包含在特征有效 id 中进行过滤
- grep - 用 ^ 排除多个模式
- string - 如果字符串当前为空或为空,则尝试设置默认字符串属性值
- go - Cobra:在不使用包全局变量的情况下为子命令提供上下文?
- sharepoint - SharePoint 工作流 2010:在编辑一项时复制到整个列表列
- arrays - 填充 IList 接口中的多维数组错误
- git - 如果我忘记运行`git mv`,如何修复重命名的文件?