IndexPage.vue 4.01 KB
Newer Older
hucy's avatar
hucy committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
<!--
 * 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();

hucy's avatar
hucy committed
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
  // 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
  );
hucy's avatar
hucy committed
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
});

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>