IndexPage.vue 2.76 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
  const pointO = { x: 600, y: 200, name: 'O' };
  const pointA = { x: 500, y: 300, name: 'A' };
  const pointB = { x: 800, y: 300, name: 'B' };
hucy's avatar
hucy committed
35 36 37 38
  drawVector(pointO, pointA);
  drawVector(pointO, pointB);

  // 加法
hucy's avatar
hucy committed
39 40 41
  const pointC = new Vector(pointO, pointA).add(pointB) as any;
  pointC.name = 'C';

hucy's avatar
hucy committed
42 43
  const len = new Vector(pointO, pointB).length;
  console.log('OB向量长度', len);
hucy's avatar
hucy committed
44 45
  const len2 = new Vector(pointA, pointB).length;
  console.log('AB向量的长度', len2);
hucy's avatar
hucy committed
46 47 48 49

  drawVector(pointO, pointC, '#21BA45');

  // 减
hucy's avatar
hucy committed
50 51 52
  const pointD = new Vector(pointO, pointB).subtract(pointA);
  console.log('pointD', pointD);
  drawVector(pointO, pointD, '#FFA000');
hucy's avatar
hucy committed
53 54 55

  // 求夹角
  const angle = new Vector(pointO, pointA).dotProduct(pointB);
hucy's avatar
hucy committed
56
  console.log('OA向量到OB向量的夹角', angle);
hucy's avatar
hucy committed
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 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
});

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>