数学篇07 # 如何用向量和参数方程描述曲线?
Posted 凯小默
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数学篇07 # 如何用向量和参数方程描述曲线?相关的知识,希望对你有一定的参考价值。
说明
【跟月影学可视化】学习笔记。
如何用向量描述曲线?
用向量绘制折线的方法来绘制正多边形
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>如何用向量描述曲线</title>
<style>
canvas
border: 1px dashed salmon;
</style>
</head>
<body>
<canvas width="512" height="512"></canvas>
<script type="module">
import Vector2D from './common/lib/vector2d.js';
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const width, height = canvas;
ctx.translate(0.5 * width, 0.5 * height);
ctx.scale(1, -1);
/**
* 边数 edges
* 起点 x, y
* 一条边的长度 step
* */
function regularShape(edges = 3, x, y, step)
const ret = [];
const delta = Math.PI * (1 - (edges - 2) / edges);
let p = new Vector2D(x, y);
const dir = new Vector2D(step, 0);
ret.push(p);
for(let i = 0; i < edges; i++)
p = p.copy().add(dir.rotate(delta));
ret.push(p);
return ret;
function draw(points, strokeStyle = 'salmon', fillStyle = null)
ctx.strokeStyle = strokeStyle;
ctx.beginPath();
ctx.moveTo(...points[0]);
for(let i = 1; i < points.length; i++)
ctx.lineTo(...points[i]);
ctx.closePath();
if(fillStyle)
ctx.fillStyle = fillStyle;
ctx.fill();
ctx.stroke();
draw(regularShape(3, 128, 128, 100)); // 绘制三角形
draw(regularShape(6, -64, 128, 50)); // 绘制六边形
draw(regularShape(11, -64, -64, 30)); // 绘制十一边形
draw(regularShape(60, 128, -64, 6)); // 绘制六十边形
</script>
</body>
</html>
如何用参数方程描述曲线?
1. 画圆
圆可以用一组参数方程来定义。定义了一个圆心在(x0,y0),半径为 r 的圆。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>画圆</title>
<style>
canvas
border: 1px dashed salmon;
</style>
</head>
<body>
<canvas width="512" height="512"></canvas>
<script>
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const width, height = canvas;
ctx.translate(0.5 * width, 0.5 * height);
ctx.scale(1, -1);
const TAU_SEGMENTS = 60;
const TAU = Math.PI * 2;
function arc(x0, y0, radius, startAng = 0, endAng = Math.PI * 2)
const ang = Math.min(TAU, endAng - startAng);
const ret = ang === TAU ? [] : [[x0, y0]];
const segments = Math.round(TAU_SEGMENTS * ang / TAU);
for(let i = 0; i <= segments; i++)
const x = x0 + radius * Math.cos(startAng + ang * i / segments);
const y = y0 + radius * Math.sin(startAng + ang * i / segments);
ret.push([x, y]);
return ret;
function draw(points, strokeStyle = 'salmon', fillStyle = null)
ctx.strokeStyle = strokeStyle;
ctx.beginPath();
ctx.moveTo(...points[0]);
for(let i = 1; i < points.length; i++)
ctx.lineTo(...points[i]);
ctx.closePath();
if(fillStyle)
ctx.fillStyle = fillStyle;
ctx.fill();
ctx.stroke();
draw(arc(0, 0, 100));
</script>
</body>
</html>
2. 画圆锥曲线
椭圆
a、b 分别是椭圆的长轴和短轴,当 a = b = r 时,这个方程是就圆的方程式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>椭圆</title>
<style>
canvas
border: 1px dashed salmon;
</style>
</head>
<body>
<canvas width="512" height="512"></canvas>
<script>
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const width, height = canvas;
ctx.translate(0.5 * width, 0.5 * height);
ctx.scale(1, -1);
const TAU_SEGMENTS = 60;
const TAU = Math.PI * 2;
function ellipse(x0, y0, radiusX, radiusY, startAng = 0, endAng = Math.PI * 2)
const ang = Math.min(TAU, endAng - startAng);
const ret = ang === TAU ? [] : [[x0, y0]];
const segments = Math.round(TAU_SEGMENTS * ang / TAU);
for(let i = 0; i <= segments; i++)
const x = x0 + radiusX * Math.cos(startAng + ang * i / segments);
const y = y0 + radiusY * Math.sin(startAng + ang * i / segments);
ret.push([x, y]);
return ret;
function draw(points, strokeStyle = 'salmon', fillStyle = null)
ctx.strokeStyle = strokeStyle;
ctx.beginPath();
ctx.moveTo(...points[0]);
for(let i = 1; i < points.length; i++)
ctx.lineTo(...points[i]);
ctx.closePath();
if(fillStyle)
ctx.fillStyle = fillStyle;
ctx.fill();
ctx.stroke();
draw(ellipse(0, 0, 100, 50));
</script>
</body>
</html>
抛物线
抛物线的参数方程。其中 p 是常数,为焦点到准线的距离。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>抛物线</title>
<style>
canvas
border: 1px dashed salmon;
</style>
</head>
<body>
<canvas width="512" height="512"></canvas>
<script>
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const width, height = canvas;
ctx.translate(0.5 * width, 0.5 * height);
ctx.scale(1, -1);
const LINE_SEGMENTS = 60;
function parabola(x0, y0, p, min, max)
const ret = [];
for(let i = 0; i <= LINE_SEGMENTS; i++)
const s = i / 60;
const t = min * (1 - s) + max * s;
const x = x0 + 2 * p * t ** 2;
const y = y0 + 2 * p * t;
ret.push([x, y]);
return ret;
function draw(points, strokeStyle = 'salmon', fillStyle = null)
ctx.strokeStyle = strokeStyle;
ctx.beginPath();
ctx.moveTo(...points[0]);
for(let i = 1; i < points.length; i++)
ctx.lineTo(...points[i]);
ctx.closePath();
if(fillStyle)
ctx.fillStyle = fillStyle;
ctx.fill();
ctx.stroke();
draw(parabola(0, 0, 5.5, -10, 10));
</script>
</body>
</html>
3. 画其他常见曲线
在 lib 下面新建一个 parametric.js
文件,封装一个更简单的 javascript 参数方程绘图模块。
// 根据点来绘制图形
function draw(
points,
context,
以上是关于数学篇07 # 如何用向量和参数方程描述曲线?的主要内容,如果未能解决你的问题,请参考以下文章