IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++程序设计六(类的继承、多态性) -> 正文阅读

[C++知识库]C++程序设计六(类的继承、多态性)

编写一个平面图形系统,实现类似Windows画图的功能:可以绘制基本的图形,比如矩形,圆形、直线段、椭圆等,可以设置形状的线条颜色/粗细/线型。要求:

1)定义一个命名空间Graphics;在该空间中开发图形系统。

2)编写一个表示画布的类Canvas,所有图形由该类维护,Canvas类有一个方法是保存绘图结果到一个bmp文件。保存bmp文件的代码在BmpIO.h和BmpIO.cpp中。Canvas类另一个方法是添加基本图形实例到画布中。其它方法根据需要自行添加。

3)编写抽象基类Shape,表示抽象的图形;

4)从Shape派生出至少两个子类,表示两种不同的图形;

5)在main函数中,生成Canvas对象,并向该对象添加几种图形实例,然后保存成位图文件。

6)尝试在Canvas中添加一个填充功能,使用FloodFill算法,从指定的种子点开始,用指定的颜色,填充一个封闭的区域。

shape.h

#ifndef _SHAPE_H_
#define _SHAPE_H_
#include <vector>
using namespace std;
namespace Graphics {
	class Point {
	public:
		int x, y;
	public:
		Point() :x(0), y(0) {}
		Point(int _x, int _y) :x(_x), y(_y) {}
		double DistanceTo(const Point p);
	};

	class Color {
	public:
		unsigned char r, g, b;
		static Color red, green, blue, white, black;
	public:
		Color() :r(0xFF), g(0xFF), b(0xFF) {}
		Color(unsigned char _r, unsigned char _g, unsigned char _b) :
			r(_r), g(_g), b(_b) {}
		Color(const Color &clr) :r(clr.r), g(clr.g), b(clr.b) {}
		friend bool operator==(const Color &c1, const Color &c2);
	};


	class Shape {
	private:
		Color lineColor;
	public:
		Shape() :lineColor(Color::black) {}
		Shape(const Color _lineColor) : lineColor(_lineColor) {}
		Shape(const Shape &s) :lineColor(s.lineColor) {}
		void setLineColor(const Color _lineColor) { lineColor = _lineColor; };
		Color getLineColor() const { return lineColor; }
		virtual void GetEdgePointList(vector<Point> &ptList) = 0;
		virtual Shape* Clone() const = 0;
		virtual ~Shape() {};
	};

	class Rect :public Shape {
	private:
		Point p;
		int width, height;
	public:
		Rect() :p(Point()), width(1), height(1) {}
		Rect(const Point &position, const int _width, const int _height) :
			p(position), width(_width), height(_height) {}
		Rect(const Color _lineColor, const Point &position,
			const int _width, const int _height) :
			Shape(_lineColor), p(position), width(_width), height(_height) {}
		Rect(const Rect &r) :Shape(r), p(r.p), width(r.width), height(r.height) {}
		Rect& operator=(const Rect &r);
		Shape* Clone() const;
		void GetEdgePointList(vector<Point> &ptList);
		~Rect() {}
	};

	class Circle :public Shape {//声明Circle类
	private:
		Point p;//圆心p点
		int r;//半径r
	public:
		Circle() :p(Point()), r(1) {}//默认构造函数
		Circle(const Point &position, const int _r) :p(position), r(_r) {}//带参构造函数
		Circle(const Color _lineColor, const Point &position, const int _r) :
			Shape(_lineColor), p(position), r(_r) {}
		Circle(const Circle&c) :Shape(c), p(c.p), r(c.r) {}//拷贝构造函数
		Circle&operator=(const Circle &c);//拷贝赋值函数
		Shape*Clone()const;
		void GetEdgePointList(vector<Point> &ptList);
	};

	class Ellipse :public Shape {//声明椭圆类
	public:
		Point p;//椭圆中心点
		int a, b;//椭圆的半长轴与半短轴
	private:
		Ellipse() :p(Point()), a(2), b(1) {}//无参构造函数,将a、b分别初始化为2、1
		Ellipse(const Point &position, const int _a, const int _b) :p(position), a(_a), b(_b) {}
		Ellipse(const Color _lineColor, const Point &position, const int _a, const int _b) :
			Shape(_lineColor), p(position), a(_a), b(_b) {}//带参构造函数
		Ellipse(const Ellipse&o) :Shape(o), p(o.p), a(o.a), b(o.b) {}//拷贝构造函数
		Ellipse&operator=(const Ellipse &o);//拷贝赋值函数
		Shape*Clone()const;
		void GetEdgePointList(vector<Point> &ptList);
	};

}
#endif

shape.cpp

#include "Shape.h"
using namespace Graphics;

Color Color::red(0xFF, 0x00, 0x00);
Color Color::green(0x00, 0xFF, 0x00);
Color Color::blue(0x00, 0x00, 0xFF);
Color Color::white(0xFF, 0xFF, 0xFF);
Color Color::black(0x00, 0x00, 0x00);
bool Graphics::operator==(const Color &c1, const Color &c2) {//加上了Graphics
	return (c1.r == c2.r) && (c1.g == c2.g) && (c1.b == c2.b);
}
double Point::DistanceTo(const Point p) {
	return sqrt((p.x - x)*(p.x - x) + (p.y - y)*(p.y - y));
}
Rect& Rect::operator=(const Rect &r) {
	if (this != &r) {
		setLineColor(r.getLineColor());
		p = r.p;
		width = r.width;
		height = r.height;
	}
	return *this;
}
Shape* Rect::Clone() const {
	return new Rect(*this);
}
void Rect::GetEdgePointList(vector<Point> &ptList) {
	ptList.clear();
	for (int i = p.x; i < p.x + width; ++i) {
		ptList.push_back(Point(i, p.y));
		ptList.push_back(Point(i, p.y + height));
	}
	for (int j = p.y; j < p.y + height; ++j) {
		ptList.push_back(Point(p.x, j));
		ptList.push_back(Point(p.x + width, j));
	}
}

Circle& Circle::operator=(const Circle &c) {
	if (this != &c) {
		setLineColor(c.getLineColor());
		p = c.p;
		r = c.r;
	}
	return *this;
}
Shape* Circle::Clone() const { return new Circle(*this); }
void Circle::GetEdgePointList(vector<Point> &ptList) {
	ptList.clear();
	if (r <= 0)return;
	double delta = std::fmax(1 / r, 1e-5);
	static const double two_pi = 3.1415926 * 2;
	for (double t = 0; t < two_pi; t += delta) {
		int x = static_cast<int>(r*cos(t) + p.x);
		int y = static_cast<int>(r*sin(t) + p.y);
		ptList.push_back(Point(x, y));
	}
}

Ellipse&Ellipse::operator=(const Ellipse &o) {
	if (this != &o) {
		setLineColor(o.getLineColor());
		p = o.p;
		a = o.a;
		b = o.b;
	}
	return *this;
}
Shape* Ellipse::Clone() const { return new Ellipse(*this); }
void Ellipse::GetEdgePointList(vector<Point> &ptList) {
	ptList.clear();
	if (a <= 0 || b <= 0)return;
	double delta = std::fmax(1 / (a), 1e-5);
	static const double two_pi = 3.1415926 * 2;
	for (double t = 0; t < two_pi; t += delta) {
		int x = static_cast<int>(a*cos(t) + p.x);
		int y = static_cast<int>(b*sin(t) + p.y);
		ptList.push_back(Point(x, y));
	}
}

Canvas.h

#ifndef _CANVAS_H_
#define _CANVAS_H_
#include "Shape.h"
#include <vector>

using namespace std;
namespace Graphics {

	class Canvas {
	private:
		int width, height;
		Color bgColor;
		vector<Shape*> allShapes;
		unsigned char *pixels;
	private:
		void ConvertToBitmap();
		void RemoveAllShapes();
	public:
		Canvas() :bgColor(Color::white), width(640), height(480), pixels(nullptr) {}
		Canvas(int _width, int _height, Color _bgColor = Color::white) :
			width(_width), height(_height), bgColor(_bgColor) {}
		Canvas(const Canvas &c);
		Canvas& operator=(const Canvas &c);

		~Canvas() {
			delete[]pixels;
			RemoveAllShapes();
		}
		void Attach(const Shape &s) {
			allShapes.push_back(s.Clone());
		}
		void ReDraw() {}
		void SaveToBitmap(const char *filename);
	};
}
#endif

Canvas.cpp

#include "Canvas.h"
#include "BmpIO.h"
using namespace Graphics;

Canvas::Canvas(const Canvas &c) {
	bgColor = c.bgColor;
	width = c.width;
	height = c.height;
	/*vector<Shape*> allShapes;
	unsigned char *pixels;*/
	unsigned char*_ptemp = new unsigned char;
	_ptemp = c.pixels;
	pixels = _ptemp;
	vector<Shape*>temp = c.allShapes;
	allShapes = temp;
}

Canvas& Canvas::operator=(const Canvas &c) {
	if (this != &c) {
		delete[]pixels;
		for (unsigned int i = 0; i < allShapes.size(); ++i) {
			delete allShapes[i];
		}
		bgColor = c.bgColor;
		width = c.width;
		height = c.height;
		/*vector<Shape*> allShapes;
		unsigned char *pixels;*/
		unsigned char*_ptemp = new unsigned char;
		_ptemp = c.pixels;
		pixels = _ptemp;
		vector<Shape*>temp = c.allShapes;
		allShapes = temp;
	}
	return *this;
}

void Canvas::RemoveAllShapes() {
	for (auto x : allShapes)delete x;
	allShapes.clear();
}
void Canvas::ConvertToBitmap() {
	if (nullptr != pixels) delete[]pixels;
	pixels = nullptr;
	int numPixels = width * height;
	if (numPixels < 1) return;
	pixels = new unsigned char[numPixels * 3];
	for (int j = 0; j < numPixels; j++) {
		pixels[3 * j + 0] = bgColor.r;
		pixels[3 * j + 1] = bgColor.g;
		pixels[3 * j + 2] = bgColor.b;
	}

	vector<Point> ptList;
	for (auto x : allShapes) {
		x->GetEdgePointList(ptList);
		Color c = x->getLineColor();
		for (auto p : ptList) {
			if (p.x >= 0 && p.x < width && p.y>0 && p.y < height) {
				int index = (p.x + p.y * width) * 3;
				pixels[index + 0] = c.r;
				pixels[index + 1] = c.g;
				pixels[index + 2] = c.b;
			}
		}
	}
}
void Canvas::SaveToBitmap(const char *filename) {
	ConvertToBitmap();
	WriteBitmap(pixels, width, height, filename);
}

BmplO.h与BmplO.cpp略

展示效果:

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-27 11:41:17  更:2021-08-27 11:42:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 4:47:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计