WEBGL學習【四】模型視圖矩陣

<html lang="zh-CN">

<!--服務器運行地址:http://127.0.0.1:8080/webgl/LearnNeHeWebGL/NeHeWebGL4.html-->
<head>
    <title>NeHe's WebGL</title>
    <meta charset="UTF-8"/>
    <!--引入需要的庫文件-->
    <script type="text/javascript" src="Oak3D_v_0_5.js"></script>

    <!--片元著色器;為JavaScript片段指定一個ID編號,后面我可以更具這個ID編號來獲取這段片元著色器的JavaScript片段代碼-->
    <script id="shader-fs" type="x-shader/x-fragment">
    precision mediump float;varying vec4 vColor;void main(void) {gl_FragColor = vColor;}</script>

    <!--頂點著色器;后面可以通過ID編號來獲取這段頂點著色器代碼-->
    <script id="shader-vs" type="x-shader/x-vertex">
    attribute vec3 aVertexPosition;attribute vec4 aVertexColor;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying vec4 vColor;void main(void) {gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);vColor = aVertexColor;}</script>


    <script type="text/javascript">

        var gl;
        //初始化WEBGL
        function initGL(canvas) {
            try {
                //獲取WEBGL上下文
                gl = canvas.getContext("experimental-webgl");
                //gl這個上下文中存放了一些屬性(canvas的寬度、長度和其他相關屬性數據)
                //設置我的視口的寬度和高度
                gl.viewportWidth = canvas.width;
                gl.viewportHeight = canvas.height;
            } catch (e) {
            }
            //如果獲取失敗
            if (!gl) {
                alert("Could not initialise WebGL, sorry :-(");
            }
        }


        //獲取我的著色器對象
        function getShader(gl, id) {
            //根據id獲取著色器源程序代碼
            var shaderScript = document.getElementById(id);
            if (!shaderScript) {
                return null;
            }

            var str = "";
            var k = shaderScript.firstChild;
            while (k) {
                if (k.nodeType == 3) {
                    str += k.textContent;
                }
                k = k.nextSibling;
            }

            var shader;
            //1.根據著色器的類型創建相應的著色器對象
            if (shaderScript.type == "x-shader/x-fragment") {
                shader = gl.createShader(gl.FRAGMENT_SHADER);
            } else if (shaderScript.type == "x-shader/x-vertex") {
                shader = gl.createShader(gl.VERTEX_SHADER);
            } else {
                return null;
            }

            //2.向著色器對象中指定相應的GLSL ES源代碼(以字符串的形式傳遞進去)
            gl.shaderSource(shader, str);
            //3.開始編譯著色器(編譯成為二進制的可執行文件)
            gl.compileShader(shader);

            //檢查下著色器的狀態(是否編譯成功)
            if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                alert(gl.getShaderInfoLog(shader));
                return null;
            }

            return shader;
        }


        //一個著色器對象必須包含一個頂點著色器和一個片元著色器
        var shaderProgram;

        //初始化著色器
        function initShaders() {
            //獲取我的頂點著色器和片元著色器
            var fragmentShader = getShader(gl, "shader-fs");
            var vertexShader = getShader(gl, "shader-vs");

            //每一個program中可以存放一個頂點著色器和一個片元著色器
            //4.創建我的程序對象
            shaderProgram = gl.createProgram();
            //5.為程序對象分配著色器對象
            gl.attachShader(shaderProgram, vertexShader);
            gl.attachShader(shaderProgram, fragmentShader);

            //6.鏈接程序對象
            /**
             * 1.可以保證頂點著色器和片元著色器同名并且是同類型的
             * 2.attributeuniformvarying變量個數不超過著色器的上限
             */
            gl.linkProgram(shaderProgram);
            //檢測是否連接成功
            if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
                alert("Could not initialise shaders");
            }
            //7.告訴WEBGL要使用的程序對象
            gl.useProgram(shaderProgram);

            //指定一個新的屬性;gl.enableVertexAttribArray,我們使用它來告訴WebGL我們會用一個數組來為屬性賦值
            //頂點的位置信息
            shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
            gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

            //獲取我的頂點著色器中的attribute顏色變量
            shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
            gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);

            //program中取得另外的兩個屬性值(模型視圖投影矩陣)
            shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
            shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
        }


        //定義了我的模型視圖矩陣和投影矩陣
        var mvMatrix;
        var pMatrix;

        //在這里實現我的矩陣的進棧和出棧操作
        var mvMatrixStack = [];
        function myPushMatrix() {
            var copy = new okMat4();
            mvMatrix.clone(copy);
            mvMatrixStack.push(copy);
        }

        function myPopMatrix() {
            if (mvMatrixStack.length == 0) {
                throw "Invalid popMatrix!";
            }
            mvMatrix = mvMatrixStack.pop();
        }

        //把我們新設置的模型視圖投影矩陣傳給頂點著色器中的uniform變量
        function setMatrixUniforms() {
            gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix.toArray());
            gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix.toArray());
        }


        //定義我的三角形和矩形緩沖區頂點位置
        var pyramidVertexPositionBuffer;
        var cubeVertexPositionBuffer;
        //定義我的三角形和矩形緩沖區的頂點顏色
        var pyramidVertexColorBuffer;
        var cubeVertexColorBuffer;
        //定義我的立方體索引下標
        var cubeVertexIndexBuffer;

        //緩沖區的初始化
        function initBuffers() {
            //1.新建三角形頂點緩沖區對象
            pyramidVertexPositionBuffer = gl.createBuffer();
            //2.綁定目標對象到緩沖區
            gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer);
            //初始化我的頂點數組
            var vertices = [
                // Front face
                0.0,  1.0,  0.0,
                -1.0, -1.0,  1.0,
                1.0, -1.0,  1.0,

                // Right face
                0.0,  1.0,  0.0,
                1.0, -1.0,  1.0,
                1.0, -1.0, -1.0,

                // Back face
                0.0,  1.0,  0.0,
                1.0, -1.0, -1.0,
                -1.0, -1.0, -1.0,

                // Left face
                0.0,  1.0,  0.0,
                -1.0, -1.0, -1.0,
                -1.0, -1.0,  1.0
            ];
            //3.緩沖區對象中寫入數據
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

            //計算頂點數組的大小和頂點個數
            pyramidVertexPositionBuffer.itemSize = 3;
            pyramidVertexPositionBuffer.numItems = 12;

            //1.創建我的顏色緩沖區
            pyramidVertexColorBuffer = gl.createBuffer();
            //2.綁定我的顏色緩沖區到目標對象
            gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer);
            //初始化我的顏色數組(對每一個頂點指定相應的顏色)
            var colors = [
                //注意保證在同一個頂點上面的顏色要相同
                // Front face
                1.0, 0.0, 0.0, 1.0,
                0.0, 1.0, 0.0, 1.0,
                0.0, 0.0, 1.0, 1.0,

                // Right face
                1.0, 0.0, 0.0, 1.0,
                0.0, 0.0, 1.0, 1.0,
                0.0, 1.0, 0.0, 1.0,

                // Back face
                1.0, 0.0, 0.0, 1.0,
                0.0, 1.0, 0.0, 1.0,
                0.0, 0.0, 1.0, 1.0,

                // Left face
                1.0, 0.0, 0.0, 1.0,
                0.0, 0.0, 1.0, 1.0,
                0.0, 1.0, 0.0, 1.0
            ];
            //3.向緩沖區對象中寫入數據
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
            //計算三角形頂點顏色數組的大小和頂點個數
            pyramidVertexColorBuffer.itemSize = 4;
            pyramidVertexColorBuffer.numItems = 12;



            //1.新建矩形頂點緩沖區對象
            cubeVertexPositionBuffer = gl.createBuffer();
            //2.綁定目標對象到緩沖區
            gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
            //立方體的頂點位置數組
            vertices = [
                // Front face(123第一個三角形, 134第二個三角形)
                -1.0, -1.0,  1.0,
                1.0, -1.0,  1.0,
                1.0,  1.0,  1.0,
                -1.0,  1.0,  1.0,

                // Back face
                -1.0, -1.0, -1.0,
                -1.0,  1.0, -1.0,
                1.0,  1.0, -1.0,
                1.0, -1.0, -1.0,

                // Top face
                -1.0,  1.0, -1.0,
                -1.0,  1.0,  1.0,
                1.0,  1.0,  1.0,
                1.0,  1.0, -1.0,

                // Bottom face
                -1.0, -1.0, -1.0,
                1.0, -1.0, -1.0,
                1.0, -1.0,  1.0,
                -1.0, -1.0,  1.0,

                // Right face
                1.0, -1.0, -1.0,
                1.0,  1.0, -1.0,
                1.0,  1.0,  1.0,
                1.0, -1.0,  1.0,

                // Left face
                -1.0, -1.0, -1.0,
                -1.0, -1.0,  1.0,
                -1.0,  1.0,  1.0,
                -1.0,  1.0, -1.0
            ];
            //3.向緩沖區對象中寫入數據
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
            //計算矩形頂點數組每一項數據的大小,和頂點個數(有四個不同的頂點位置,每個頂點由3個數字組成)
            cubeVertexPositionBuffer.itemSize = 3;
            cubeVertexPositionBuffer.numItems = 24;

            //1.創建我的立方體的頂點顏色緩沖區
            cubeVertexColorBuffer = gl.createBuffer();
            //2.綁定目標對象到緩沖區
            gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer);
            //定義我的矩形的顏色數組
            colors = [
                [1.0, 0.0, 0.0, 1.0], // Front face[red]
                [1.0, 1.0, 0.0, 1.0], // Back face[yellow]
                [0.0, 1.0, 0.0, 1.0], // Top face[green]
                [1.0, 0.5, 0.5, 1.0], // Bottom face[]
                [1.0, 0.0, 1.0, 1.0], // Right face[]
                [0.0, 0.0, 1.0, 1.0]  // Left face[blue]
            ];

            //對于矩形的四個頂點賦予相同的顏色
            //每一個面的四個頂點都是同樣的顏色
            /***
             * 1.0, 0.0, 0.0, 1.0
             * 1.0, 0.0, 0.0, 1.0
             * 1.0, 0.0, 0.0, 1.0
             * 1.0, 0.0, 0.0, 1.0
             * 1.0, 1.0, 0.0, 1.0
             * 1.0, 1.0, 0.0, 1.0
             * 1.0, 1.0, 0.0, 1.0
             * 1.0, 1.0, 0.0, 1.0
             * ………………………………
             * 0.0, 0.0, 1.0, 1.0
             * 0.0, 0.0, 1.0, 1.0
             * 0.0, 0.0, 1.0, 1.0
             * 0.0, 0.0, 1.0, 1.0
             * @type {Array}
             */
            var unpackedColors = [];
            for (var i in colors) {
                var color = colors[i];
                for (var j=0; j < 4; j++) {
                    unpackedColors = unpackedColors.concat(color);
                }
            }

            //3.向緩沖區對象中寫入數據
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(unpackedColors), gl.STATIC_DRAW);
            //計算我的正方形的頂點數組
            cubeVertexColorBuffer.itemSize = 4;
            cubeVertexColorBuffer.numItems = 24;


            //開始定義我的頂點位置數組
            //1.創建我的頂點索引緩沖區對象
            cubeVertexIndexBuffer = gl.createBuffer();
            //2.綁定目標對象到緩沖區
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
            //設置我的頂點索引數組
            var cubeVertexIndices = [
                0, 1, 2,      0, 2, 3,    // Front face
                4, 5, 6,      4, 6, 7,    // Back face
                8, 9, 10,     8, 10, 11,  // Top face
                12, 13, 14,   12, 14, 15, // Bottom face
                16, 17, 18,   16, 18, 19, // Right face
                20, 21, 22,   20, 22, 23  // Left face
            ];
            //3.向緩沖區對象寫入數據
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
            //計算我的頂點索引數組的大小(每一項數據的大小,總共36個數據)
            /**
             * 1個不同的頂點位置(numItems),每個頂點由36個數字組成(itemSize             * @type {number}
             */
            cubeVertexIndexBuffer.itemSize = 1;
            cubeVertexIndexBuffer.numItems = 36;
        }


        //定義我的三角形和我的矩形的初始旋轉角度
        var rPyramid = 0;
        var rCube = 0;

        //繪制我的場景(三角形和矩形)
        function drawScene() {
            //設置視口大小
            gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
            //清空顏色緩存和深度緩存
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

            //建立一個透視投影(視場角,視口比例,最近,最遠距離)
            pMatrix = okMat4Proj(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0);

            //新建一個模型視圖矩陣
            mvMatrix = new okMat4();
            //保存矩陣的初始狀態
            myPushMatrix();


            //設置我的模型視圖矩陣為平移矩陣
            //mvMatrix = okMat4Trans(-1.5, 0.0, -7.0);
            mvMatrix.translate(OAK.SPACE_WORLD, -1.5, 0.0, -8.0, true);
            //三角形的椎體繞著Y軸旋轉(本地坐標系旋轉)
            mvMatrix.rotY(OAK.SPACE_LOCAL, rPyramid, true);

            //1.綁定三角形頂點數據到緩沖區對象
            gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer);
            gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, pyramidVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);

            //2.綁定三角形顏色信息到緩沖區對象,并且傳遞給頂點著色器
            gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer);
            gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, pyramidVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);



            //告訴WEBGL當前使用的模型視圖投影矩陣
            setMatrixUniforms();
            //開始繪制三角形(從第0個位置開始,繪制numItems個頂點)
            gl.drawArrays(gl.TRIANGLES, 0, pyramidVertexPositionBuffer.numItems);
            //繪制完畢后再次恢復我的模型視圖矩陣
            myPopMatrix();


            //再次保存我的模型視圖矩陣
            myPushMatrix();
            //開始繪制立方體
            mvMatrix.translate(OAK.SPACE_WORLD, 1.5, 0.0, -8.0, true);
            //讓我的矩形繞著XYZ軸旋轉
            //mvMatrix.rotX(OAK.SPACE_LOCAL, rCube, true);
            mvMatrix.rot(OAK.SPACE_LOCAL, rCube, 1.0, 1.0, 1.0, true);

            //綁定四邊形的頂點信息(與索引下標綁定在一起)
            gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
            gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, cubeVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);


            //開始傳遞顏色數據
            gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer);
            gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, cubeVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);

            //開始綁定索引下標信息
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);

            setMatrixUniforms();

            //開始繪制立方體
            //gl.drawArrays(gl.TRIANGLE_STRIP, 0, cubeVertexPositionBuffer.numItems);
            gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);

            //繪制完畢后,恢復我的模型視圖矩陣的初始狀態
            myPopMatrix();
        }


        //這里是我的主函數
        function webGLStart() {
            //獲取canvas元素
            var canvas = document.getElementById("lesson01-canvas");

            //初始化WEBGL上下文信息
            initGL(canvas);

            //初始化著色器
            initShaders();

            //出事阿虎緩沖區
            initBuffers();

            //指定清空畫布的顏色,開啟隱藏面消除的功能
            gl.clearColor(0.0, 0.0, 0.0, 1.0);
            gl.enable(gl.DEPTH_TEST);

            //開始繪制我的場景
            //drawScene();
            //開始使用動畫效果來繪制我的圖形
            tick();
        }

        //實現我的動畫繪制函數
        function tick() {
            //重復調用tick函數
            okRequestAnimationFrame(tick);

            //開始繪制場景
            drawScene();

            //改變我的三角形和我的矩陣的旋轉角度
            animate();
        }

        //開始不斷修改我的旋轉角度
        var lastTime = 0;
        function animate() {
            var timeNow = new Date().getTime();
            if (lastTime != 0) {
                var elapsed = timeNow - lastTime;

                //三角形 90/s, 矩形 75/s
                rPyramid += (90 * elapsed) / 1000.0;
                rCube -= (75 * elapsed) / 1000.0;
            }
            lastTime = timeNow;
        }

    </script>


</head>

<body οnlοad="webGLStart();">
<canvas id="lesson01-canvas" style="border: none;" width="500" height="500"></canvas>
</body>

</html>

轉載于:https://www.cnblogs.com/52tech/p/9325124.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/454238.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/454238.shtml
英文地址,請注明出處:http://en.pswp.cn/news/454238.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用Jmeter對mysql進行性能測試入門

使用Jmeter對mysql進行性能測試入門 第一步&#xff1a;測試環境準備&#xff1a; 1&#xff09;、mysql> select version(); ----------- | version() | ----------- | 5.5.13 | ----------- ms數據庫數據&#xff1a; mysql> select count(*) from account; ----------…

算法基礎之數據結構

whats the 數據結構 數據結構是指相互之間存在著一種或多種關系的數據元素的集合和該集合中數據元素之間的關系組成。 簡單來說&#xff0c;數據結構就是設計數據以何種方式組織并存儲在計算機中。 比如&#xff1a;列表、集合與字典等都是一種數據結構。 通常情況下&#xff…

soap接口怎么不返回tuple python_Python 中的接口

Python 是動態類型語言, 只在運行時做 Duck Typing 檢查.利: 靈活, 方便弊: 代碼混亂, 缺少規范標準自帶兩類接口支持: abc 和 typing.Protocol, 有他們協助給天馬行空的程序員套上枷鎖, Python 的大工程才可以"上道"abcabc 就是 Abstract Base Class, 虛基類. 跟 Ja…

java 第11次作業:你能看懂就說明你理解了——this關鍵字

this 代表當前對象 轉載于:https://www.cnblogs.com/qingyundian/p/7736699.html

c#多線程操作界面控件的簡單實現

一個小功能&#xff0c;早有人實現了。自己在一個項目中用到&#xff0c;覺得有必要記錄一下&#xff0c;寫下來。代碼 從上面你可能已經看出如何多線程操作同一個控件的&#xff0c;就是通過一個委托&#xff0c;然后定義委托方法&#xff0c;判斷控件的InvokeRequired屬性&am…

ssh 免密_Linux下配置SSH免密通信 “sshkeygen”的基本用法

利用 SSH 協議可以有效防止遠程管理過程中的信息泄露問題。SSH最初是UNIX系統上的一個程序&#xff0c;后來又迅速擴展到其他操作平臺。1 什么是SSH引用百度百科的說明:SSH 為 Secure Shell的縮寫&#xff0c;由 IETF 的網絡小組(Network Working Group)所制定&#xff1b;它是…

Python 第三方模塊之 NumPy - 科學計算

NumPy 簡介 NumPy 發展歷史 1995年 Jim HugUNin開發了Numeric。隨后&#xff0c;Numarray包誕生。Travis Oliphants整合Numeric和Numarray&#xff0c;開發Numpy&#xff0c;于2006年發布第一個版本。Numpy&#xff08;Numeric Python&#xff09;提供了許多高級的數值編程工…

keepalived與lvs結合使用配置實例

keepalived可以實現兩大功能是&#xff1a;健康檢測和故障轉移 keepalived.conf的配置 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950global_defs {notification_email { acassenfirewall.loc failoverfirewall.loc sysadminf…

保證你現在和未來不失業的十種關鍵技術

在當今的IT就業市場&#xff0c;有人歡喜有人憂。有人對目前的工作和薪水很滿意&#xff0c;有人目前正面臨著下崗&#xff0c;或者已經下崗…… 可能你是公司里唯一諳熟某項關鍵技術的高手&#xff0c;缺了你&#xff0c;公司便玩不轉了&#xff1b;也可能你所在的公司對你現…

python設置時間步長與時間離散格式_python怎么定義時間

Python 的 Decorator在使用上和Java/C#的Annotation很相似&#xff0c;就是在方法名前面加一個XXX注解來為這個方法裝飾一些東西。但是&#xff0c;Java/C#的Annotation也很讓人望而卻步&#xff0c;太TMD的復雜了&#xff0c;你要玩它&#xff0c;你需要了解一堆Annotation的類…

Python 第三方模塊之 matplotlib - 繪圖庫

簡介 matplotlib是受MATLAB的啟發構建的。MATLAB是數據繪圖領域廣泛使用的語言和工具。MATLAB語言是面向過程的。利用函數的調用&#xff0c;MATLAB中可以輕松的利用一行命令來繪制直線&#xff0c;然后再用一系列的函數調整結果。 matplotlib有一套完全仿照MATLAB的函數形式…

python 筆記(三) 斷言(assert)

用來調試程序的時候用&#xff0c;當程序有誤時&#xff0c;強制拋出異常轉載于:https://www.cnblogs.com/wangkeblog/p/7746022.html

網站程序員的程序員成長之路大概分幾個階段 和未來的發展

信息技術的更新速度是驚人的&#xff0c;程序員的職業生涯則是一個要求不斷學習的過程&#xff0c;如何才能成為一名合格的程序員&#xff0c;一名合格的程序員需要掌握哪些技能呢&#xff1f;為此天天招生網采訪到幾位孳生的程序工作人員&#xff0c;就如何做好一名成功的程序…

微軟P2V工具之Disk2VHD

虛擬化經過最近幾年的發展&#xff0c;已經有很多的應用和服務遷移到了虛擬化的平臺上了。在實施虛擬化的過程中就會涉及到將原來老舊的服務器來遷移到虛擬化平臺的運行&#xff0c;這就是P2V&#xff0c;物理機轉換為虛擬機。談到P2V大家會想到很多的工具&#xff0c;例如Vmwa…

生成n套數位加減乘除_leetcode 算法匯總(四)位運算

一、 運算符& 與運算&#xff1a; 兩個位都是 1 時&#xff0c;結果才為 1&#xff0c;否則為 0| 或運算&#xff1a; 兩個位都是 0 時&#xff0c;結果才為 0&#xff0c;否則為 1^ 異或運算&#xff1a; 兩個位相同則為 0&#xff0c;不同則為 1~ 取反運算&#xff1a;0 …

機器學習算法之 K-means、層次聚類,譜聚類

k-means 和層次聚類都屬于劃分聚類&#xff0c;實際中最常用的是k-means&#xff0c;k-means效果不好的情況下才會采用其他聚類 K-means算法 K-means算法&#xff0c;也稱為K-平均或者K-均值&#xff0c;是一種使用廣泛的最基礎的聚類算法 假設輸入樣本為TX1,X2,…,Xm;則算法…

vue數據請求

我是vue菜鳥&#xff0c;第一次用vue做項目&#xff0c;寫一些自己的理解&#xff0c;可能有些不正確&#xff0c;歡迎糾正。 vue開發環境要配置本地代理服務。把config文件加下的index.js里的dev添加一些內容&#xff0c; dev: {env: require(./dev.env),port: 8090,autoOpenB…

jetty部署多個web應用及將jetty配置成服務

通常情況下一個jetty部署一個java web應用&#xff0c;但一臺服務只部署一個應用可能會造成資源浪費&#xff0c;所以有時候可能在一臺服務器上要部署多個web應用。下面我們以一臺server部署兩個web應用為例。 服務器環境&#xff1a;安裝JDK&#xff0c;2個jetyy9 重點&#x…

程序員成長的10個階段

我的程序員成長之路 程序員的成長經歷往往很相似&#xff0c;大部分的人走過了最前面相同的一段路&#xff0c;而有的人則走得更遠。總結自己這些年來的歷程&#xff0c;這也許能讓年輕的程序員少走一些彎路&#xff0c;成長得更快&#xff1b;或許更好一些&#xff0c;能讓大家…

mapper注解的主要作用_Mybatis中mapper的xml解析詳解

上一篇文章分析了mapper注解關鍵類MapperAnnotationBuilder&#xff0c;今天來看mapper的項目了解析關鍵類XMLMapperBuilder。基礎介紹回顧下之前是在分析configuration的初始化過程&#xff0c;已經進行到了最后一步mapperElement(root.evalNode("mappers"))&#x…