最近儿子数学课已经进入平面解析几何的学习了。因为小朋友现在的空间想象能力还处于培养阶段,所以我想尽可能使用一些可视化的工具来辅助他理解一些数学概念。 来看一道 B 卷题目:将点 p(-2,4) 绕点O顺时针旋转45度后对应的点坐标为多少?
对于学过了高等数学的我们来说,可以使用二维向量的旋转矩阵来轻易解决这个问题:
对于点 P(x,y)P(x, y)P(x,y),绕原点旋转角度 θ\thetaθ 的旋转矩阵如下:

其中,θ 是旋转的角度。在本题中,角度为 45 度,且是顺时针旋转,因此 θ=−45∘。 求出旋转矩阵的值:
然后把 P 点的坐标代入旋转矩阵,计算即可。
最后得到答案。
但是上面使用了线性代数的旋转矩阵概念,小朋友在初中还没有学,只能用勾股定律来求解。
于是我让 Trae 使用 html,css 和 JavaScript,写一个演示动画效果。
给 Trae 发出的指令很简单:
使用 html,css 和 JavaScript,写一个演示动画效果,将点 p(-2,4) 绕点O顺时针旋转45度后对应的点坐标为多少?

这里最有价值的就是让 Trae 绘制出旋转的动画效果。
先看 Trae 绘制的最终效果,如下图所示:
点击开始动画按钮之后,能看到点 P 慢慢的进行旋转,到达最终的目的点。
如下图所示:
从程序员的视角出发,Trae 这个解决方案可圈可点。 全部代码仅仅 300 多行,但精确实现了点的顺时针旋转效果:
我们来简单看看 Trae 的旋转动画效果到底是怎么实现的。
html
<style>
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}
#canvas-container {
position: relative;
width: 500px;
height: 500px;
margin: 20px 0;
border: 1px solid #ccc;
}
canvas {
position: absolute;
top: 0;
left: 0;
}
这部分设置了页面的样式。页面的主体使用了 flexbox
布局,确保元素垂直居中排列。#canvas-container
是画布的容器,其宽高均为 500px,且具有一个 1px 的边框,确保画布区域的可视化。
canvas
元素的位置被设置为绝对定位,确保两个 <canvas>
元素重叠在一起,分别用于绘制网格和旋转动画。
再来看看结果显示部分
html
.result {
margin-top: 20px;
padding: 15px;
background-color: #f5f5f5;
border-radius: 5px;
width: 80%;
max-width: 500px;
}
.math {
font-family: 'Times New Roman', Times, serif;
margin: 10px 0;
line-height: 1.5;
}
结果区域显示了点旋转的计算过程。该区域背景颜色为浅灰色,并具有一定的内外边距,使得内容更加易读。数学公式部分采用了经典的 Times New Roman
字体,以突出公式的专业性。
接下来是解决方案的重头戏:绘图和动画的 JavaScript 部分, 它负责计算旋转后的点坐标,并动态地在画布上绘制坐标轴、点和动画。
javascript
const gridCanvas = document.getElementById('gridCanvas');
const animationCanvas = document.getElementById('animationCanvas');
const gridCtx = gridCanvas.getContext('2d');
const animCtx = animationCanvas.getContext('2d');
这里获取了两个 <canvas>
元素,并分别为其设置了绘图上下文 gridCtx
和 animCtx
,以便分别在一个画布上绘制坐标网格,另一个画布上绘制动画。
javascript
const centerX = 250;
const centerY = 250;
const scale = 30; // 每单位长度对应的像素数
设置了坐标系的中心位置为 (250, 250)
,即画布的中心,并定义了 scale
,即每单位数学坐标对应多少像素。这样就能根据给定的数学坐标将点绘制到画布上。
javascript
const initialPoint = { x: -2, y: 4 };
const rotationAngle = 45; // 旋转角度
这里定义了初始点的坐标 P(-2, 4)
,并设置旋转角度为 45 度。
旋转点的计算:
javascript
function rotatePoint(point, angleDegrees) {
const angleRadians = angleDegrees * Math.PI / 180;
const cos = Math.cos(angleRadians);
const sin = Math.sin(angleRadians);
return {
x: point.x * cos + point.y * sin,
y: -point.x * sin + point.y * cos
};
}
该函数通过数学公式计算给定点绕原点顺时针旋转一定角度后的新坐标。旋转公式为:
x' = x * cos(θ) + y * sin(θ)
y' = -x * sin(θ) + y * cos(θ)
绘制坐标系的逻辑:
javascript
function drawGrid() {
gridCtx.clearRect(0, 0, gridCanvas.width, gridCanvas.height);
// 绘制网格线、坐标轴、坐标标签和刻度
}
该函数用于绘制坐标网格、坐标轴以及相应的标签和刻度线,使得点的位置可以通过数学坐标轻松找到。
接下来是小朋友最喜欢的动画效果的实现:
javascript
function animate() {
let currentAngle = 0;
const finalAngle = rotationAngle;
const rotatedPoint = rotatePoint(initialPoint, finalAngle);
const fps = 60;
const duration = 2000; // 2秒
const frames = duration / 1000 * fps;
const angleIncrement = finalAngle / frames;
let frameCount = 0;
function draw() {
animCtx.clearRect(0, 0, animationCanvas.width, animationCanvas.height);
// 绘制当前点的位置
}
draw();
}
animate
函数用来实现动画效果。它每次更新当前旋转角度,并在每一帧上绘制旋转后的点,直到完成 45 度的旋转。动画持续时间为 2 秒,并使用 requestAnimationFrame
实现平滑动画。
由此可见,Trae 生成代码的质量非常高,水平丝毫不逊于一个中级水平的前端开发人员。我咋觉得越来越有危机感了......