如何通过循环在摆钟钟面圆周自动绘制罗马数字小时刻度
圆周循环排布罗马数字时钟刻度实现方法
你现有圆点刻度的绘制逻辑已经跑通了圆周等分的核心思路,画罗马数字不需要套旋转矩阵(会把位图文字转歪),直接用三角函数计算每个刻度的坐标定位绘制即可,核心步骤如下:
- 提前预置12个小时对应的罗马数字字符串数组,顺序和12点到11点的刻度一一对应
- 按每格30度的间隔,用三角函数计算每个刻度点的x、y坐标
- 针对位图文字的宽度做居中偏移,循环调用位图字符绘制接口输出对应罗马数字即可
具体实现代码参考
首先定义罗马数字映射表,放在全局或者绘制函数开头都可以:
#include <math.h> #include <string.h> // 数组顺序对应:12点、1点、2点……11点的刻度文字 const char* roman_num[] = {"XII", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI"};
替换手动逐个写文字的部分,用循环批量绘制:
const float PI = 3.142f; // 罗马数字所在圆周半径,和你手动写XII时的y坐标0.68对齐 const float num_radius = 0.68f; // 单字符居中偏移系数,适配GLUT_BITMAP_HELVETICA_18字体,和你手动写XII时的x偏移-0.025匹配 const float char_width_offset = 0.0083f; for (int i = 0; i < 12; i++) { // 三角函数默认0度指向3点钟方向,偏移90度让起始点对准12点位置,每格减30度 float rad = (90.0f - i * 30.0f) * PI / 180.0f; float pos_x = cos(rad) * num_radius; float pos_y = sin(rad) * num_radius; // 按当前文字长度计算x轴偏移,让文字居中在刻度点上 int str_len = strlen(roman_num[i]); float total_offset = str_len * char_width_offset; // 定位并绘制文字 glRasterPos3f(pos_x - total_offset, pos_y, 0); for (int j = 0; j < str_len; j++) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, roman_num[i][j]); } }
优化提示
- 你之前绘制圆点刻度的循环条件写的
i <=12,会在0度位置重复绘制1次12点的圆点,改成i <12即可避免冗余绘制 - 如果后续更换字体,文字居中位置不准,只需要微调
char_width_offset的数值就行,不用改核心循环逻辑 - 不要在glRotate旋转矩阵的作用域内直接调用glutBitmapCharacter绘制位图文字,否则文字会跟着矩阵旋转变成倒转/倾斜状态,直接计算坐标定位不会有这个问题
内容的提问来源于stack exchange,提问作者stealth
相关产品推荐
相关产品推荐

