PascalABC.NET中如何将直角坐标外次摆线转换为极坐标实现
外次摆线极坐标绘制实现方案
外次摆线不存在以极角为单一自变量的简洁单值极坐标方程$\rho=f(\theta)$,无法直接通过单值函数完成绘制,教学和工程场景下的标准实现方式是通过参数方程计算点集后转换为极坐标,完全可以满足课程项目要求。
核心逻辑说明
参数对应关系
和你已完成的直角坐标代码参数完全一致:
- 固定基圆半径:
r1 - 沿基圆外侧滚动的动圆半径:
r2 - 绘图点到动圆圆心的偏移距离:
h - 比例系数
m = r2/r1,循环变量t是动圆转过的角度参数,不是极坐标系下的极角
坐标转换规则
你现有代码中的直角坐标参数方程是正确的:
$$
\begin{cases}
x_{offset} = r_1(1+m)\cos(mt) - h\cos((1+m)t) \
y_{offset} = r_1(1+m)\sin(mt) - h\sin((1+m)t)
\end{cases}
$$
对每个参数t对应的直角坐标偏移量,做极坐标换算即可得到极坐标点对:
- 极径:$\rho = \sqrt{x_{offset}^2 + y_{offset}^2}$
- 极角:$\theta = \arctan2(y_{offset}, x_{offset})$
注意:必须用
ArcTan2函数计算极角,不能用普通反正切函数,否则会出现象限判断错误,导致图形断裂错位。PascalABC.NET的Math单元自带该函数可直接调用。
这种方式是标准的极坐标绘制流程:每个轨迹点的极径、极角都经过独立计算,不存在不符合要求的问题;不要强行推导单值极坐标闭式表达式——外次摆线存在折返/自交结构,同一个极角下可能对应2个及以上极径点,单值函数必然出现丢段、错形问题。
极坐标版本PascalABC.NET实现代码
uses graphABC, Math; var c, x_screen, y_screen: integer; r1, r2, m, h, t, ms, rho, theta_polar: real; begin SetWindowSize(500, 500); CenterWindow; c := 250; // 窗口中心即极坐标原点 r1 := 1; r2 := 0.2; m := r2/r1; h := 0.3; ms := (c-50)/(r1 + 2*r2); // 图形缩放系数 // 可选:绘制极坐标参考网格 SetPenColor(clGray); SetPenWidth(1); // 极径同心圆网格 for var i := 1 to 4 do Circle(c, c, round(i*r1*ms/2)); // 极角射线网格 for var ang := 0 to 7 do begin var rad := ang * Pi/4; Line(c, c, c + round((c-50)*cos(rad)), c - round((c-50)*sin(rad))); end; // 绘制固定基圆 SetPenWidth(2); SetPenColor(clGreen); Circle(c, c, round(r1*ms)); // 极坐标方式绘制外次摆线 SetPenColor(clRed); t := 0; while t <= 2*Pi do // 统一用弧度计算,精度更高 begin // 计算参数方程相对坐标 var x_off := (r1*(m+1)*cos(m*t) - h*cos((m+1)*t))*ms; var y_off := (r1*(m+1)*sin(m*t) - h*sin((m+1)*t))*ms; // 转换为极坐标值 rho := Sqrt(x_off*x_off + y_off*y_off); theta_polar := ArcTan2(y_off, x_off); // 极坐标映射到屏幕像素坐标 x_screen := c + round(rho * cos(theta_polar)); y_screen := c - round(rho * sin(theta_polar)); if t = 0 then MoveTo(x_screen, y_screen) else LineTo(x_screen, y_screen); t := t + 0.001; end; end.
原直角坐标系实现效果参考

内容的提问来源于stack exchange,提问作者Abisurin
相关产品推荐
相关产品推荐

