You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过循环在摆钟钟面圆周自动绘制罗马数字小时刻度

圆周循环排布罗马数字时钟刻度实现方法

你现有圆点刻度的绘制逻辑已经跑通了圆周等分的核心思路,画罗马数字不需要套旋转矩阵(会把位图文字转歪),直接用三角函数计算每个刻度的坐标定位绘制即可,核心步骤如下:

  • 提前预置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 13:15:41