<!-- * JavaScript 线性代数:向量 * https://juejin.cn/post/6844903859689619469 --> <script setup lang="ts"> import { reactive, onMounted } from 'vue'; import { Vector } from './utils'; interface Point { x: number; y: number; gap?: number; [proppName: string]: any; } const stageSize = reactive({ width: 1200, height: 800, gridGap: 100, }); const state = reactive({ canvasDom: null as any, pen: null as any, }); onMounted(() => { state.canvasDom = document.getElementById('canvas-grid'); state.pen = state.canvasDom.getContext('2d'); drawGrid(); // const pointO = { x: 600, y: 200, name: 'O' }; // const pointA = { x: 500, y: 300, name: 'A' }; // const pointB = { x: 800, y: 300, name: 'B' }; // drawVector(pointO, pointA); // drawVector(pointO, pointB); // // 加法 // const pointC = new Vector(pointO, pointA).add(pointB) as any; // pointC.name = 'C'; // const len = new Vector(pointO, pointB).length; // console.log('OB向量长度', len); // const len2 = new Vector(pointA, pointB).length; // console.log('AB向量的长度', len2); // drawVector(pointO, pointC, '#21BA45'); // // 减 // const pointD = new Vector(pointO, pointB).subtract(pointA); // console.log('pointD', pointD); // drawVector(pointO, pointD, '#FFA000'); // // 求夹角 // const angle = new Vector(pointO, pointA).dotProduct(pointB); // console.log('OA向量到OB向量的夹角', angle); const pointP = { x: 400, y: 200, name: 'P' }; const pointP1 = { x: 700, y: 200, name: 'P1' }; const pointP2 = { x: 300, y: 400, name: 'P2' }; drawVector(pointP, pointP1); drawVector(pointP, pointP2); // 单位化后的向量以(0,0)点为原点 // 单位化PP1向量 const pointP1fterUnit = new Vector(pointP, pointP1).unitization(); // 单位化PP2向量 const pointP2fterUnit = new Vector(pointP, pointP2).unitization(); const unitP1 = pointP1fterUnit.point; const myUnitP1 = { x: unitP1.x * 100, y: unitP1.y * 100 }; const _myUnitP1 = { x: myUnitP1.x + pointP.x, y: myUnitP1.y + pointP.y }; drawVector(pointP, _myUnitP1, 'pink'); const unitP2 = pointP2fterUnit.point; const myUnitP2 = { x: unitP2.x * 100, y: unitP2.y * 100 }; const _myUnitP2 = { x: myUnitP2.x + pointP.x, y: myUnitP2.y + pointP.y }; drawVector(pointP, _myUnitP2, 'pink'); // PQ的单位向量 // = 单位化PP1向量 + 单位化PP2向量 const unitPQ = new Vector(pointP, _myUnitP1).add(_myUnitP2); drawVector(pointP, unitPQ, 'pink'); console.log('PQ的单位向量', unitPQ); console.log( '单位化PP1向量', pointP1fterUnit, '单位化PP2向量', pointP2fterUnit ); }); function drawVector(pointX: Point, pointY: Point, color = '#F44336') { const pen = state.pen; pen.save(); pen.beginPath(); pen.moveTo(pointX.x, pointX.y); pen.lineTo(pointY.x, pointY.y); pen.lineWidth = 4; pen.strokeStyle = color; pen.stroke(); pen.fillText(pointX.name, pointX.x, pointX.y); pen.fillText(pointY.name, pointY.x, pointY.y); pen.restore(); } // 网格线 function drawGrid() { let canvas: any = document.getElementById('canvas-grid'); let pen = canvas.getContext('2d'); // 绘制网格 const step = stageSize.gridGap; const h = stageSize.height; const w = stageSize.width; const w_l = w / step; const h_l = h / step; // 横着的线 pen.save(); for (let i = 0; i <= h_l; i++) { pen.beginPath(); pen.moveTo(0, i * step); pen.lineTo(w, i * step); pen.stroke(); } // 竖着的线 for (let i = 0; i <= w_l; i++) { pen.beginPath(); pen.moveTo(i * step, 0); pen.lineTo(i * step, h); pen.stroke(); } pen.restore(); } </script> <template> <div class="center"> <div class="canvas-box"> <canvas id="canvas-grid" :width="stageSize.width" :height="stageSize.height" style="position: absolute" ></canvas> </div> </div> </template> <style lang="scss" scoped> .canvas-box { box-sizing: border-box; width: 1200px; height: 800px; border: 1px solid #000; position: relative; } </style>