《从零开始写 Canvas 引擎》——极坐标系作业

沉淀

  • 效果图:

  • 源码:

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
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
92
93
94
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Line Basic</title>
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta charset="utf-8">
<style>
html, body {
height: 100%;
}
body {
margin: 0;
padding: 0;
background-color: rgb(42, 42, 42);
}
</style>
<body>
<canvas id="canvas-1" width="1024" height="768" style="background-color: antiquewhite;margin:30px;"></canvas>
</body>
<script>
let canvas = document.getElementById('canvas-1');
let context = canvas.getContext('2d');
let width = canvas.width;
let height = canvas.height;

let origin = [width/2, height/2];

let x1 = origin[0]+100;
let y1 = origin[1]+40;

let x2 = origin[0] + 140;
let y2 = origin[1] + 120;

//计算线段相对于极轴的旋转角,返回弧度
function calcRadian(x1,y1,x2,y2){
let radian = Math.atan2(y2-y1,x2-x1);
return radian;
}

//计算两个蓝色点的坐标
function calcPoints(x,y,len,lineRadian,arrowRadian){
let x1=len*Math.cos(lineRadian+arrowRadian);
let y1=len*Math.sin(lineRadian+arrowRadian);
let x2=len*Math.cos(lineRadian-arrowRadian);
let y2=len*Math.sin(lineRadian-arrowRadian);
return [[x1+x,y1+y],[x2+x,y2+y]];
}

// 计算画出来的连线相对于极轴的旋转角度
// let lineRadian = Math.atan2(y2 - y1, x2 - x1);
// 调用atan2(起点y-终点y, 起点x-终点x)
let lineRadian = calcRadian(x2,y2,x1,y1);

// 箭头二分之一的夹角, PI/4 应该是一个等腰直角三角形
let rowRadian = Math.PI/4;
// 首先计算点(x1, y1)附近的两个三角形的点
// 1. +rowRadian, len: 三角形腰长
let len=20;
// let x1_1 = len*Math.cos(lineRadian + rowRadian)+x2;
// let y1_1 = len*Math.sin(lineRadian + rowRadian)+y2;
// let x1_2 = len*Math.cos(lineRadian - rowRadian)+x2;
// let y1_2 = len*Math.sin(lineRadian - rowRadian)+y2;
let points = calcPoints(x2, y2, len, lineRadian, rowRadian);

// 画出线条
context.moveTo(x1, y1);
context.lineTo(x2, y2);
context.stroke();
// context.lineTo(x1_1, y1_1);
context.lineTo(points[0][0], points[0][1]);
context.stroke();
// context.lineTo(x1_2, y1_2);
context.lineTo(points[1][0], points[1][1]);
context.stroke();
context.lineTo(x2, y2);
context.stroke();
context.fill();

// 画出第二个箭头
// 计算【最初的起点】与极轴的夹角, 此时起始点与终点对调了
let startLineRadian = calcRadian(x2,y2,x1,y1);
// -Math.PI 旋转180°?
let startPoints = calcPoints(x1, y1, len, startLineRadian-Math.PI, rowRadian);
context.lineTo(x1, y1);
context.lineTo(startPoints[0][0], startPoints[0][1]);
context.lineTo(startPoints[1][0], startPoints[1][1]);
context.lineTo(x1, y1);
context.stroke();
context.fill();
</script>
</html>