基于OpenCV Turtle Graphics的交错偏移砖墙绘制问题求助(C++作业)
我正在学习C++,目前被一项作业任务难住了:要求使用嵌套循环绘制交错偏移半块砖的砖墙。我已经实现了绘制完整砖块(fullBrick)和半砖块(halfBrick)的函数,并且成功绘制出一行9块砖(9块砖刚好铺满窗口宽度),但在进行下一步时遇到了阻碍。
我需要让程序在完成第一行绘制后继续绘制下一行,然而"\n"和cout << endl;仅对控制台窗口生效,无法影响OpenCV打开的TurtleWindow。我了解到这需要使用changePosition命令来调整位置,但不清楚如何将其整合到循环中——如果直接设置固定的(x, y)坐标,会不会导致每次循环都将砖块绘制在同一位置?希望能得到相关帮助,我感觉离解决方案很近,但这一步确实难住我了。
以下是我的代码:
// BrickWall.cpp : This file contains the 'main' function. Program execution begins //and ends there. // #include <iostream> #include "opencv2/core.hpp" #include "opencv2/imgproc.hpp" #include "opencv2/highgui.hpp" #include <stdio.h> #include <math.h> using namespace cv; using namespace std; #define M_PI 3.14159265358979323846264338327950288 #define degToRad(angleInDegrees) ((angleInDegrees) * M_PI / 180.0) char wndname[] = "TurtleWindow"; Mat image = Mat::zeros(500, 500, CV_8UC3); Scalar WHITE(255, 255, 255); const int DELAY = 1; Point _curPosition(250, 250); int _direction = 0; void init() { imshow(wndname, image); waitKey(DELAY); } // // Move the pen to the given coordinates without leaving a mark // // Note (0,0) refers to the upper left corner // (500,500) refers to the bottom right corner // void changePosition(int x, int y) { _curPosition.x = x; _curPosition.y = y; } // // point in the direction given in degrees // 0 ==> point right // 90 ==> point down // 180 ==> point left // 270 ==> point up // void changeDirection(int direction) { _direction = direction; } // // Moves the pen forward the given number of pixels // Note leaves a mark creating a line from the previous point // to the new point // void moveForward(int nPixels) { int x = static_cast<int>(round(nPixels * cos(degToRad(_direction)))); int y = static_cast<int>(round(nPixels * sin(degToRad(_direction)))); Point newPoint = Point(x + _curPosition.x, y + _curPosition.y); line(image, _curPosition, newPoint, WHITE); _curPosition = newPoint; // cout << "moved to " << newPoint.x << "," << newPoint.y << endl; imshow(wndname, image); waitKey(DELAY); } void fullBrick() // changePosition(25, 25); { changeDirection(0); moveForward(50); changeDirection(90); moveForward(20); changeDirection(180); moveForward(50); changeDirection(270); moveForward(20); changeDirection(0); moveForward(50); } void halfBrick() //changePosition(25, 45); { changeDirection(0); moveForward(25); changeDirection(90); moveForward(20); changeDirection(180); moveForward(25); changeDirection(270); moveForward(20); } int main() { int counter; int counterWall; counterWall = 0; counter = 0; init(); changePosition(25, 25); while (counter < 20) { do { changeDirection(0); moveForward(50); changeDirection(90); moveForward(20); changeDirection(180); moveForward(50); changeDirection(270); moveForward(20); changeDirection(0); moveForward(50); counterWall++; } while (counterWall < 9); counter++; } waitKey(); }
解决方案建议
别担心,你确实离解决办法很近了!核心就是利用changePosition逐行调整绘制的起始位置,同时区分奇偶行的偏移量,实现交错效果。咱们一步步拆解:
跟踪每行的垂直位置
从你的fullBrick函数能看出来,每块砖的高度是20像素。你可以用一个变量(比如currentY)来记录当前行的起始Y坐标,每画完一行就给currentY加上20,这样下一行就会自动下移,绝对不会重复绘制在同一位置。给偶数行添加水平偏移
交错砖墙的关键是奇偶行错位半块砖:奇数行(第1、3、5...行)从X=25开始,偶数行(第2、4、6...行)从X=25+25=50开始(半块砖的长度是25)。用行号取模row % 2 == 1就能轻松判断是否需要偏移。重构嵌套循环结构
把你现在的多层循环改成清晰的双层循环:外层控制行数,内层控制每行的砖块数。这样逻辑更直观,也更容易维护。比如修改后的main函数可以写成这样:int main() { init(); const int totalRows = 10; // 可自行调整想要的行数 const int bricksPerRow = 9; // 刚好铺满窗口的砖块数 int currentY = 25; // 第一行的起始Y坐标 for (int row = 0; row < totalRows; row++) { int startX = 25; // 偶数行偏移半块砖的位置 if (row % 2 == 1) { startX += 25; } // 移动到当前行的起始点 changePosition(startX, currentY); // 绘制当前行的所有砖块 for (int brick = 0; brick < bricksPerRow; brick++) { fullBrick(); // 你的fullBrick函数画完后会自动跳到下一个砖的位置 } // 下移一行的高度 currentY += 20; } waitKey(); }利用已有的半砖函数(可选)
如果你想画更标准的交错砖墙(偶数行以半砖开头和结尾),可以调整内层循环:偶数行先调用halfBrick,再画8次fullBrick,最后再补一个halfBrick。不过需要注意计算起始位置,确保刚好铺满窗口宽度,这就看作业的具体要求啦。
看到你说已经提交作业并且成功完成了,真的很棒!那种靠自己解决问题的成就感确实让人开心😉
内容的提问来源于stack exchange,提问作者snowysnowy

