如何基于C++实现自定义参数的Hourglass类字符画沙漏Draw方法
沙漏字符画实现的推导思路
先拆解图形结构
不用急着写循环,先把整体图形拆成可复用的模块,避免逻辑混乱:
- 完整沙漏本质是两个反向的三角形拼接:上半部分是顶点在上、底边在图形正中间的倒三角,下半部分是顶点在下、顶边在图形正中间的正三角,两个三角完全共享中间最宽的那一行作为公共拼接边,这样不会出现重复绘制、上下错位的问题。
- 任意一行的输出内容固定只有三类元素,你只需要对每一行算清楚三类元素的数量,就能准确输出该行:
- 行首需要补的前置空格数(作用是让整个沙漏水平居中,不会歪)
- 行的左右轮廓位置(统一用构造函数传入的
border字符标记) - 两个轮廓之间的内部区域(统一用构造函数传入的
fill字符填充)
推导上半倒三角的参数规律
别凭空推公式,对着你参考过的尺寸6的效果逐行计数,数3行以上自然能摸到规律:
- 上半部分总共占
size行,从最顶端的三角尖开始,一直画到中间最宽的公共拼接边行。 - 逐行记录两个核心参数:
- 每往下走一行(从尖到中间公共边),行首的前置空格逐行递减1,这样两个边框会慢慢往左右两侧分开
- 同样逐行记录两个边框之间的填充字符数:从最顶端尖部的0个填充(两个border刚好挨在一起)开始,往公共边走的时候填充数逐行递增,到公共边行时填充数达到最大值。
注意:所有行的总宽度要保持一致,前置空格数的计算只要保证「前置空格数 + 当前行内容总宽度 = 固定最大宽度」就行,这样图形不会歪。
下半正三角直接复用参数,不用重新计算
下半部分是上半部分的垂直镜像,完全没必要重新写一套参数计算逻辑:
- 上半部分画完
size行到中间公共边之后,下半部分只需要把上半部分的行参数从倒数第二行开始,倒着往前逐行输出就行。比如上半按顺序画了第0行(顶部尖)、第1行…第size-1行(中间公共边),下半部分就按第size-2行、第size-3行…第0行的顺序循环输出对应行的内容。 - 这种做法的好处是不用重复写计算逻辑,还能保证上下完全对称,不会出现大小不一、错位的问题。
嵌套循环的结构搭建
你之前猜到要用嵌套循环的思路是完全正确的,循环层次非常清晰:
- 最外层大循环控制行的输出顺序:先循环
size次完成上半部分的行绘制,再循环size-1次完成下半镜像部分的行绘制,总输出行数就是2*size -1,刚好匹配沙漏的结构。 - 针对每一行,内层只需要拆成3个小循环依次输出即可:
- 循环输出对应数量的前置空格
- 先输出左侧border字符,循环输出对应数量的fill字符,最后输出右侧border字符
- 输出完当前行所有内容后打换行,进入下一行
容易踩的避坑点
- 不要混淆border和fill的使用范围:border只放在每行的左右轮廓位置,fill只放在两个轮廓中间的内部区域,不要把fill打在轮廓位,也不要把border打在填充区。
- 不要重复绘制中间公共边的那一行:因为公共边是上下三角共享的,上半部分已经画过了,下半部分循环的时候要从公共边的上一行开始倒序输出,不然会出现中间行重复、图形变形的问题。
- 你现在已经写完的
size==1的特殊判断逻辑可以直接复用,只需要在size>1的分支里把上面的循环逻辑接上就行,不用改动原有特殊场景的判断。
内容的提问来源于stack exchange,提问作者Rams
相关产品推荐
相关产品推荐

