当前位置: 首页 > news >正文

吉林市网站推广网站建设应注意哪些问题

吉林市网站推广,网站建设应注意哪些问题,做企业网站备案收费吗,宁波外贸公司电话名单目录 多个简单模型组成的复杂模型 层次结构模型 单关节模型 JointModel程序中模型的层次结构 示例程序#xff08;JointMode.js#xff09; 代码详解 绘制层次模型#xff08;draw#xff08;#xff09;#xff09; 程序效果 多个简单模型组成的复杂模型 绘制…目录 多个简单模型组成的复杂模型 层次结构模型 单关节模型 JointModel程序中模型的层次结构 示例程序JointMode.js  代码详解  绘制层次模型draw 程序效果 多个简单模型组成的复杂模型 绘制由多个小部件组成的复杂模型最关键的问题是如何处理模型的整体移动以及各个小部件间的相对移动。现在就来研究这个问题。首先考虑一下人类的手臂从肩部到指尖包括上臂肘以上、前臂肘以下、手掌和手指如下图所示。 手臂的每个部分可以围绕关节运动如上图所示 ● 上臂可以绕肩关节旋转运动并带动前臂、手掌和手指一起运动。 ● 前臂可以绕肘关节运动并带动手掌和手指一起运动但不影响上臂。 ● 手掌绕腕关节运动并带动手指一起运动但不影响上臂和前臂。 ● 手指运动不影响上臂、前臂和手掌。 总之当手臂的某个部位运动时位于该部位以下的其他部位会随之一起运动而位于该部位以上的其他部位不受影响。此外这里的所有运动都是围绕某个关节肩关节、肘关节、腕关节、指关节的转动。  层次结构模型 绘制机器人手臂这样一个复杂的模型最常用的方法就是按照模型中各个部件的层次顺序从高到低逐一绘制并在每个关节上应用模型矩阵。比如在图9.2中肩关节、肘关节、腕关节指关节都有各自的旋转矩阵。 注意三维模型和现实中的人类或机器人不一样它的部件并没有真正连接在一起。如果直接转动上臂那么肘部以下的部分包括前臂、手掌和手指只会留在原地这样手臂就断开了。所以当上臂绕肩关节转动时你需要在代码中实现“肘部以下部分跟随上臂转动”的逻辑。具体地上臂绕肩关节转动了多少度肘部以下的部分也应该绕肩关节转动多少度。 当情况较为简单时实现“部件A转动带动部件B转动”可以很直接只要对部件B也施以部件A的旋转矩阵即可。比如使用模型矩阵使上臂绕肩关节转动30度然后在绘制肘关节以下的各部位时为它们施加同一个模型矩阵也令其绕肩关节转动30度如下图所示。这样肘关节以下的部分就能自动跟随上臂转动了。 肘部以下部分随着上臂转动 如果情况更复杂一些比如先使上臂绕肩关节转动30度然后使前臂绕肘关节转动10度那么对肘关节以下的部分你就得先施加上臂绕肩关节转动30度的矩阵可称为“肩关节模型矩阵”然后再施加前臂绕肘关节转动10度的矩阵。将这两个矩阵相乘其结果可称为“肘关节模型矩阵”那么在绘制肘关节以下部分的时候直接应用这个所谓的“肘关节模型矩阵”而不考虑肩关节因为肩关节的转动信息已经包含在该矩阵中了作为模型矩阵就可以了。 按照上述方式编程三维场景中的肩关节就能影响肘关节使得上臂的运动带动前臂的运动反过来不管前臂如何运动都不会影响上臂。这就与现实中的情况相符合了。  现在你已经对这种由多个小模型组成的复杂模型的运动规律有了一些了解下面来看一下示例程序。 单关节模型 先来看一个单关节模型的例子。示例程序JointModel绘制了一个仅由两个立方体部件组成的机器人手臂其运行结果如下图左所示手臂的两个部件为arm1与arm2arm1接在arm2的上面如下图右所示。你可以把arm1想象成上臂而把arm2想象成前臂而肩关节在最下面上臂在下而前臂在上是为了以后加入手掌和手指后看得更清楚。 JointModel程序中模型的层次结构 运行程序用户可以使用左右方向键控制arm1同时带动整条手臂水平转动使用上下方向键控制arm2绕joint1关节垂直转动。比如先按下方向键arm2逐渐向前倾斜下图左然后按右方向键arm1向右旋转下图右。  如你所见arm2绕joint1的转动并不影响arm1而arm1的转动会带动arm2一起转动。 示例程序JointMode.js  如下显示了JointMode.js的代码所有用来绘制和控制机器人手臂的逻辑都在JavaScript代码中。 var VSHADER_SOURCE // p316attribute vec4 a_Position;\n attribute vec4 a_Normal;\n uniform mat4 u_MvpMatrix;\n // 模型视图投影矩阵uniform mat4 u_NormalMatrix;\n // 用于改变法向量的矩阵uniform vec3 u_LightColor;\n // 平行光颜色uniform vec3 u_AmbientColor;\n // 环境光颜色varying vec4 v_Color;\n void main() {\n gl_Position u_MvpMatrix * a_Position;\n // 光照计算使场景更加逼真 vec3 lightDirection normalize(vec3(0.0, 0.5, 0.7));\n // 归一化光线方向 vec4 color vec4(1.0, 0.4, 0.0, 1.0);\n // 物体颜色 vec3 normal normalize((u_NormalMatrix * a_Normal).xyz);\n // 归一化法向量 float nDotL max(dot(normal, lightDirection), 0.0);\n // 点积 cos vec3 ambient u_AmbientColor * color.rgb;\n // 环境反射光颜色 vec3 diffuse u_LightColor * color.rgb * nDotL;\n // 漫反射光颜色 v_Color vec4(diffuse ambient, color.a);\n // 最终颜色}\n;var FSHADER_SOURCE #ifdef GL_ES\n precision mediump float;\n #endif\n varying vec4 v_Color;\n void main() {\n gl_FragColor v_Color;\n }\n;function main() {var canvas document.getElementById(webgl);var gl getWebGLContext(canvas);if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) returnvar n initVertexBuffers(gl);gl.clearColor(0.0, 0.0, 0.0, 1.0);gl.enable(gl.DEPTH_TEST);var u_MvpMatrix gl.getUniformLocation(gl.program, u_MvpMatrix);var u_NormalMatrix gl.getUniformLocation(gl.program, u_NormalMatrix);var u_LightColor gl.getUniformLocation(gl.program, u_LightColor);var u_AmbientColor gl.getUniformLocation(gl.program, u_AmbientColor);gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);gl.uniform3f(u_AmbientColor, 0.0, 1.0, 1.0);// 计算视图投影矩阵var viewProjMatrix new Matrix4();viewProjMatrix.setPerspective(50.0, canvas.width / canvas.height, 1.0, 100.0);viewProjMatrix.lookAt(20.0, 10.0, 30.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);// 注册键盘事件响应函数document.onkeydown function(ev){ keydown(ev, gl, n, viewProjMatrix, u_MvpMatrix, u_NormalMatrix); };draw(gl, n, viewProjMatrix, u_MvpMatrix, u_NormalMatrix); // 绘制立方体 }var ANGLE_STEP 3.0; // 每次按键转动的角度 var g_arm1Angle 0.0; // arml的当前角度 var g_joint1Angle 0.0; // joint1的当前角度即arm2的角度 function keydown(ev, gl, n, viewProjMatrix, u_MvpMatrix, u_NormalMatrix) {switch (ev.keyCode) {case 38: // 上方向键 - joint1绕z轴正向转动if (g_joint1Angle 135.0) g_joint1Angle ANGLE_STEP;break;case 40: // 下方向键 - joint1绕z轴负向转动if (g_joint1Angle -135.0) g_joint1Angle - ANGLE_STEP;break;case 39: // 右方向键 - arm1绕Y轴正方向转动g_arm1Angle (g_arm1Angle ANGLE_STEP) % 360;break;case 37: // 左方向键 - arm1绕Y轴负方向转动g_arm1Angle (g_arm1Angle - ANGLE_STEP) % 360;break;default: return;}// 绘制手臂draw(gl, n, viewProjMatrix, u_MvpMatrix, u_NormalMatrix); } function initVertexBuffers(gl) {// 顶点坐标长方体宽度3.0高度10.0长度3.0原点位于底部中心var vertices new Float32Array([1.5, 10.0, 1.5, -1.5, 10.0, 1.5, -1.5, 0.0, 1.5, 1.5, 0.0, 1.5, // v0-v1-v2-v3 front1.5, 10.0, 1.5, 1.5, 0.0, 1.5, 1.5, 0.0,-1.5, 1.5, 10.0,-1.5, // v0-v3-v4-v5 right1.5, 10.0, 1.5, 1.5, 10.0,-1.5, -1.5, 10.0,-1.5, -1.5, 10.0, 1.5, // v0-v5-v6-v1 up-1.5, 10.0, 1.5, -1.5, 10.0,-1.5, -1.5, 0.0,-1.5, -1.5, 0.0, 1.5, // v1-v6-v7-v2 left-1.5, 0.0,-1.5, 1.5, 0.0,-1.5, 1.5, 0.0, 1.5, -1.5, 0.0, 1.5, // v7-v4-v3-v2 down1.5, 0.0,-1.5, -1.5, 0.0,-1.5, -1.5, 10.0,-1.5, 1.5, 10.0,-1.5 // v4-v7-v6-v5 back]);// 法向量var normals new Float32Array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, // v0-v1-v2-v3 front1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, // v0-v3-v4-v5 right0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // v0-v5-v6-v1 up-1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, // v1-v6-v7-v2 left0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, // v7-v4-v3-v2 down0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0 // v4-v7-v6-v5 back]);// 顶点的索引var indices new Uint8Array([0, 1, 2, 0, 2, 3, // front4, 5, 6, 4, 6, 7, // right8, 9,10, 8,10,11, // up12,13,14, 12,14,15, // left16,17,18, 16,18,19, // down20,21,22, 20,22,23 // back]);// 将顶点属性写入缓冲区坐标和法线if (!initArrayBuffer(gl, a_Position, vertices, gl.FLOAT, 3)) return -1;if (!initArrayBuffer(gl, a_Normal, normals, gl.FLOAT, 3)) return -1;gl.bindBuffer(gl.ARRAY_BUFFER, null);var indexBuffer gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);return indices.length; }function initArrayBuffer(gl, attribute, data, type, num) {var buffer gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, buffer);gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);var a_attribute gl.getAttribLocation(gl.program, attribute);gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);gl.enableVertexAttribArray(a_attribute);return true; }// 坐标变换矩阵 var g_modelMatrix new Matrix4(), g_mvpMatrix new Matrix4();function draw(gl, n, viewProjMatrix, u_MvpMatrix, u_NormalMatrix) {gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);// Arm1var arm1Length 10.0; // Length of arm1g_modelMatrix.setTranslate(0.0, -12.0, 0.0);g_modelMatrix.rotate(g_arm1Angle, 0.0, 1.0, 0.0); // 绕y轴旋转drawBox(gl, n, viewProjMatrix, u_MvpMatrix, u_NormalMatrix); // 绘制// Arm2g_modelMatrix.translate(0.0, arm1Length, 0.0);    // 移动至joint1处g_modelMatrix.rotate(g_joint1Angle, 0.0, 0.0, 1.0); // 绕z轴旋转g_modelMatrix.scale(1.3, 1.0, 1.3); // 使立方体粗一点drawBox(gl, n, viewProjMatrix, u_MvpMatrix, u_NormalMatrix); // 绘制 }var g_normalMatrix new Matrix4(); // 法线的旋转矩阵// 绘制立方体 function drawBox(gl, n, viewProjMatrix, u_MvpMatrix, u_NormalMatrix) {// 计算模型视图投影矩阵并传给u_MvpMatrix变量g_mvpMatrix.set(viewProjMatrix);g_mvpMatrix.multiply(g_modelMatrix); // 模型 视图投影 相乘得到最终矩阵gl.uniformMatrix4fv(u_MvpMatrix, false, g_mvpMatrix.elements);// 计算法线变换矩阵并传给u_NormalMatrix变量g_normalMatrix.setInverseOf(g_modelMatrix);g_normalMatrix.transpose();gl.uniformMatrix4fv(u_NormalMatrix, false, g_normalMatrix.elements);// 最终绘制gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0); } 代码详解  主要的变化发生在initVertexBuffers函数它将arm1和arm2的数据写入了相应的缓冲区。以前程序中的立方体都是以原点为中心且边长为2.0本例为了更好地模拟机器人手臂使用如下图所示的立方体原点位于底面中心底面是边长为3.0的正方形高度为10.0。将原点置于立方体的底面中心是为了便于使立方体绕关节转动比如肘关节就位于前臂立方体的底面中心如上图所示。arm1和arm2都使用这个立方体。 用来绘制机器人前臂和上臂的立方体 main函数首先根据可视空间视点和视线方向计算出了视图投影矩阵viewProjMatrix第4446行。  然后在键盘事件响应函数中调用keydown函数第48行通过方向键控制机器人的手臂运动。  接着定义keydown函数本身第55行以及若干该函数需要用到的全局变量第52、53和54行。  ANGLE_STEP常量第52行表示每一次按下按键arm1或joint1转动的角度它的值是3.0。g_arm1Angle变量第53行表示arm1的当前角度g_joint1Angle变量表示joint1的也就是arm2的当前角度如下图所示。  g_joint1Angle和g_arm1Angle keydown函数第55行的任务是根据按下的是哪个按键对g_joint1Angle或g_arm1Angle变量加上或减去常量ANGLE_STEP的值。注意joint1的转动角度只能在-135度到135度之间这是为了不与arm1冲突。最后draw函数将整个机器人手臂绘制出来。  绘制层次模型draw draw函数的任务是绘制机器人手臂第128行。注意draw函数和drawBox函数用到了全局变量g_modelMatrix和g_mvpMatrix第126行。 如你所见draw函数内部调用了drawBox函数每调用一次绘制一个部件先绘制下方较细arm1再绘制上方较粗arm2。  绘制单个部件的步骤是1调用setTranslate或translate进行平移2调用rotate进行旋转3调用drawBox进行绘制。 绘制整个模型时需要按照各部件的层次顺序先arm1后arm2再执行1平移2旋转3绘制。 绘制arm1的步骤如下首先在模型矩阵g_modelMatrix上调用setTranslate函数使之平移0.0-12.00.0到稍下方位置第133行然后调用rotate函数绕y轴旋转g_arm1Angle角度第134行最后调用drawBox函数绘制arm1。 接着来绘制arm2它与arm1在joint1处连接如图g_joint1Angle和g_arm1Angle所示我们应当从该处上开始绘制arm2。但是此时模型矩阵还是处于绘制arm1的状态向下平移并绕y轴旋转下所以得先调用translate函数沿y轴向上平移arm1的高度arm1Length第138行。注意这里调用的是translate而不是setTranslate因为这次平移是在之前的基础上进行的。  然后使用g_joint1Angle进行肘关节处的转动第139行并在x和z轴稍作拉伸第140行使前臂看上去粗一些以便与上臂区分开。  这样一来每当keydown函数更新了g_joint1Angle变量和g_arm1Angle变量的值然后调用draw函数进行绘制时就能绘制出最新状态的机器人手臂arm1的位置取决于g_arm1Angle变量而arm2的位置取决于g_jointAngle变量当然也受g_arm1Angle的影响。 drawBox函数的任务是绘制机器人手臂的某一个立方体部件如上臂或前臂。它首先计算模型视图投影矩阵传递给u_MvpMatrix变量第149151行然后根据模型矩阵计算法向量变换矩阵传递给u_NormalMatrix变量第153155行最后绘制立方体第157行。 程序效果
http://www.dnsts.com.cn/news/147658.html

相关文章:

  • 建设机械网站机构深圳 企业 网站建设哪家好
  • 网站建设是一个什么的过程怎么免费做网站教程
  • 专科网站开发就业方向电子商务网站建设汇报PPT
  • 网站建设部署与发布如何做教育网站
  • 网站建设业务员论坛网站策划是什么
  • ps企业网站模板聚名网注册
  • 给个网站你知道丽江做网站
  • 外贸网站建设平台有哪些计算机网站建设招聘
  • 深圳市年检在哪个网站做甘肃网络推广软件
  • 韩国优秀网站设计欣赏做网站需要提供什么
  • nas 做网站企业网站建站哪家好
  • 服务器网站慢的原因网站ftp用户名和密码是什么
  • 二手交易网站建设方案自己怎么做装修网站
  • 网站导航如何做半透明渐变网站建设的违约责任怎么写
  • 网站建设延期报告广州市建设和水务局网站
  • 企业网站禁忌正规网站建设服务
  • 青岛网站设计公司哪家好公司建设网站流程图
  • 做视频直播类型的网站带分销的小程序
  • wordpress 谷歌广告插件免费网站建设seo
  • 厦门网站建设 九来微信微官网开发
  • 网站群建设 公司企查查企业信息查询在线
  • 不用源码做网站搜索引擎入口大全
  • 重庆永川微网站建设大发快三网站自做
  • 网站备案网站要有内容吗成都华阳有没有做网站的
  • 网站怎么做舆情监测flash个人网站动画
  • 枣阳网站建设建材网站开发
  • 从零开始做一个网站需要多少钱wordpress 优化''
  • 怎么查询菠菜网站做没作弊成都网站建设网站建设
  • 有网站地图的网站工作证模板word
  • 做网站收费吗seo整站优化解决方案