|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 丶不离不弃 于 2019-11-6 10:32 编辑
最近老师布置了一个有加分的题目就是让我们用C++来画bitmap,老师的要求如下:int main() {
// FIRST PART (ADD COLORS HERE)
constexpr uint32_t BLACK = 0xFF000000; // black opaque
constexpr uint32_t RED = 0xFF0000FF; // red opaque
constexpr uint32_t BLUE = 0xFFFF0000;//blue opaque
constexpr uint32_t WHITE = 0xFF0000FF;
constexpr uint32_t YELLOW = 0xFF0000FF;
// SECOND PART (DO NOT EDIT)
int xcenter = 100;
int ycenter = 100;
int xdiameter = 200;
int ydiameter = 100;
Bitmap b(BLACK); // Hardcoded size (***800 x 600 pixels***)
b.horizLine(0, 500, 200, RED); // Red horizontal line, from x=0 to x=500, at y = 200
b.vertLine(0, 399, 300, RED); // Red vertical line, from y=0 to y=399, at x = 300
b.drawRect(200,200, 100,50, BLUE); // Blue rectangle, TOP-LEFT at x=200, y=200. width=100, height=50
b.fillRect(201,201, 98,48, WHITE); // White rectangle, same rules as above, but filled with color
b.line(400,0, 550,300, YELLOW); // Line drawn using https://en.wikipedia.org/wiki/Bresenham's_line_algorithm
b.ellipse(xcenter, ycenter, xdiameter, ydiameter); //Ellipse using specs from above
b.save("bitmap.png");
// THIRD PART - OPTIONAL FUNCTION
// 100pt bonus for properly implementing Wu's antialiasing
//https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
//b.antialiasedLine(400,0, 550,300, YELLOW);
}
老师要求我们写的程序中要有头文件,我在github找了半天找到了个,但是我编译了一下有错https://github.com/StevensDeptEC ... b/stb_image_write.h
然后我写的程序部分就是用布雷森汉姆直线画法以及画椭圆部分不是特别明白,请问有大神可以帮我解决一下吗?谢谢!
我的代码如下:#include <iostream>
#include <cmath>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <cstdint>
using namespace std;
#include "stb_image_write.h"
#include "stb.image.h"
#define x0 400 //定义全局变量x0,y0:坐标轴中心(x0,y0)
#define y0 300
class Bitmap{
private:
constexpr static uint32_t w=800;
constexpr static uint32_t h=600;
uint32_t pixels[w][h];
public:
Bitmap(uint32_t v){
for(uint32_t i=0; i<h; i++){
for(uint32_t j=0; j<w; j++){
pixels[i][j]=v;
}
}
}
void horizLine(uint32_t x1, uint32_t x2, uint32_t y, uint32_t v) {
for (uint32_t i = x1; i <= x2; i++) {
pixels[y][i]=v;
}
}
void vertLine(uint32_t y1, uint32_t y2, uint32_t x, uint32_t v){
for(uint32_t j=y1; j<=y2; j++){
pixels[j][x]=v;
}
}
void fillRect(uint32_t x, uint32_t y, uint32_t w, uint32_t h,uint32_t v){
for(uint32_t i=y; i<=y+h; i++){
for(uint32_t j=x; j<=x+w; j++){
pixels[i][j]=v;
}
}
}
void drawRect(uint32_t x, uint32_t y, uint32_t w, uint32_t h,uint32_t v){
for(uint32_t i=y; i<=y+w; i++){
pixels[x][i]=v;
pixels[x+h][i]=v;
}
for(uint32_t j=x; j<=x+h; j++){
pixels[j][y]=v;
pixels[j][y+w]=v;
}
}
void line(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint32_t v) {
/*
int Dx = x2 - x1;
int Dy = y2 - y1;
bool flag = false;
if (abs(Dy) > abs(Dx)) {
flag = true;
}
if (flag) {
swap(x1, y1);
swap(x2, y2);
}
if (x1 > x2) {
swap(x1, x2);
swap(y1, y2);
}
Dx = x2 - x1;
int a = y2 - y1;
Dy = abs(a);
int Er = Dx / 2;
double Der = Dy / Dx;
int Ystep;
int endy = y1;
*/
int dx=x2-x1;//gain x
int dy=y2-y1;//gain y
int q=(2*dy)-dx;
int doubleDy=2*dy;
int doubleD=2*(dy-dx);
int pointx;
int pointy;
//set two variable to display position
if(x1>x2){
pointx=x2;
pointy=y2;
x2=x1;
}
else{
pointx=x1;
pointy=y1;
}
while(pointx<x2){
pointx++;
if(q<0){
q+=doubleDy;
}
else{
pointy++;
q+=doubleD;
}
for(uint32_t i=x1;i<=x2; i++){
for(uint32_t j=y1; j<=y2;j++){
pixels[i][j]=v;
}
}
}
}
void ellipse(uint32_t xcenter, uint32_t ycenter, uint32_t xdiameter, uint32_t ydiameter, uint32_t v) {
int X;
int Y;
int a = xdiameter / 2;
int b = ydiameter / 2;
const double PI = 3.14;
double del = 0.001;
for (double i = -PI; i < PI; i = i + del) {
Y = ycenter + b * sin(i);
X = xcenter + a * cos(i);
pixels[Y][X] = v;
}
}
void save(const char filename[]) {
stbi_write_png(filename, w, h, 4, pixels, w*4);
}
};
int main() {
// FIRST PART (ADD COLORS HERE)
constexpr uint32_t BLACK = 0xFF000000; // black opaque
constexpr uint32_t RED = 0xFF0000FF; // red opaque
constexpr uint32_t BLUE = 0xFFFF0000;//blue opaque
constexpr uint32_t WHITE = 0xFF0000FF;
constexpr uint32_t YELLOW =0xFF0000FF;
constexpr uint32_t GREEN =0xFF0000FF;
// SECOND PART (DO NOT EDIT)
int xcenter = 100;
int ycenter = 100;
int xdiameter = 200;
int ydiameter = 100;
Bitmap b(BLACK); // Hardcoded size (***800 x 600 pixels***)
b.horizLine(0, 500, 200, RED); // Red horizontal line, from x=0 to x=500, at y = 200
b.vertLine(0, 399, 300, RED); // Red vertical line, from y=0 to y=399, at x = 300
b.drawRect(200,200, 100,50, BLUE); // Blue rectangle, TOP-LEFT at x=200, y=200. width=100, height=50
b.fillRect(201,201, 98,48, WHITE); // White rectangle, same rules as above, but filled with color
b.line(400,0, 550,300, YELLOW); // Line drawn using https://en.wikipedia.org/wiki/Bresenham's_line_algorithm
b.ellipse(xcenter, ycenter, xdiameter, ydiameter,GREEN); //Ellipse using specs from above
b.save("bitmap.png");
// THIRD PART - OPTIONAL FUNCTION
// 100pt bonus for properly implementing Wu's antialiasing
//https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
//b.antialiasedLine(400,0, 550,300, YELLOW);
}
此外我还有如下问题:
1.下面这部分代码是用二维数组来做的,直线画法中如果用吴晓琳直线画法有额外的加分,但是我看了很久都不是特别会。
2.老师还有个建议是用动态数组来做,这个我到现在还没头绪,请问有人能教下我咋写的吗?老师上课的例子如下:#include <iostream>
#include <cstdint>
using namespace std;
class Bitmap {
private:
uint32_t w, h;
uint32_t* b;
public:
Bitmap(uint32_t w, uint32_t h, uint32_t pixel)
: w(w), h(h), b(new uint32_t[w*h])
{
for (uint32_t i = 0; i < w*h; i++)
b[i] = pixel;
}
Bitmap() : w(0), h(0), b(nullptr) {}
~Bitmap() {
delete [] b;
}
Bitmap(const Bitmap& orig) :
w(orig.w), h(orig.h), b(new uint32_t[orig.w*orig.h]) {
memcpy(b, orig.b, sizeof(uint32_t) * w * h);
}
#if 0
this is the old way!!
Bitmap& operator =(const Bitmap& orig) {
if (this != &orig) {
delete [] b;
w = orig.w;
h = orig.h;
b = new uint32_t[w*h];
memcpy(b, orig.b, sizeof(uint32_t) * w * h);
}
return *this;
}
#endif
//modern approach: copy and swap
Bitmap& operator =(Bitmap orig) {
w = orig.w;
h = orig.h;
swap(b, orig.b);
return *this;
}
Bitmap(Bitmap&& orig) : w(orig.w), h(orig.h), b(orig.b) {
orig.b = nullptr;
}
};
Bitmap makemeapicture() {
Bitmap b(1024, 768, 0x0);
return b;
}
int main() {
Bitmap b(100,200, 0xFF000000);
Bitmap b2(b); //copy constructor
Bitmap b3(150,100, 0xFFFF);
b3 = b2;
b3 = b3;
b2 = b3 = b;
}
本帖最后由 superbe 于 2019-11-7 15:18 编辑
一些修改
void fillRect(uint32_t x, uint32_t y,uint32_t w, uint32_t h, uint32_t v){
/*for(uint32_t i=x; i<=y+h; i++){
for(uint32_t j=y; j<= x+w; j++){
m[i*j]=v;
}
}*/
for(uint32_t i = x; i <= x + w; i++)
for(uint32_t j = y; j <= y + h; j++){
m[i + j * cols] = v;
}
}
/* 这个函数有问题,画出的线位置不对,两个程序的line代码都改掉。参考Bresenham算法链接里的伪代码修改吧。
或参考我上面程序的line代码(也是照链接改的)。吴小林算法链接里也有伪代码,也照着编写吧。 */
void line(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint32_t v){
。。。
}
void ellipse(uint32_t xcenter, uint32_t ycenter, uint32_t xdiameter, uint32_t ydiameter, uint32_t v){
uint32_t X;
uint32_t Y;
uint32_t a = xdiameter / 2;
uint32_t b = ydiameter / 2;
const double PI = 3.14;
double del = 0.001;
for (double i = -PI; i < PI; i = i + del) {
Y = ycenter + b * sin(i);
X = xcenter + a * cos(i);
//m[Y*rows+X] = v; //这行不对,改成下行
m[Y * cols + X] = v;
}
}
void save(const char filename[]) {
//stbi_write_png(filename, rows, cols, 4, m, rows*cols * 4);
stbi_write_png(filename, cols, rows, 4, m, cols * 4);
}
修改后运行测试,只有line画线不正确。
|
|