鱼C论坛

 找回密码
 立即注册
查看: 1021|回复: 5

[已解决]求解关于C++写ghostview画图程序的问题

[复制链接]
发表于 2019-10-16 10:32:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 丶不离不弃 于 2019-10-16 10:36 编辑

我们老师布置了一个作业就是利用C++来写ghostview(或者adobe)的指令,生成一个test.ps文件来画各种图形,然后来填充颜色。填充颜色是setrgbcolor,分别画出一个填充红色的矩形,画一个边框为红色的矩形,
连续画6个填充红色的矩形,接着画一个绿色边框的圆,直线,和6边形。里面的数据分别是起始点x,y,宽,高。polygon中时外接圆圆心的左边,外接圆半径以及边的数目。
然后我遇到个问题就是,我这个程序setrgbcolor只是在最开始出现2个语句,并不是在画每个图形的时候都出现,这导致绿色把红色都覆盖了,请问哪位大神能帮我把程序改改?谢谢!!
  1. #include <iostream>
  2. #include <fstream>
  3. #include <vector>
  4. #include <cmath>
  5. const double PI=3.141592653;
  6. using namespace std;

  7. class Shape{
  8. private:
  9.     double r, g, b;
  10.     ofstream f;
  11. public:
  12.     void setrgb(double r, double g, double b){
  13.         f<<r<<' '<<g<<' '<<b<<" setrgbcolor "<<endl;
  14.     }
  15.     virtual void draw(ostream& s) = 0;
  16. };

  17. class Circle:public Shape{
  18. private:
  19.     double x,y,radius;
  20. public:
  21.     Circle(double x, double y, double radius):x(x),y(y),radius(radius){}
  22.     void draw(ostream& f){
  23.         f<<x<<' '<<y<<' '<<radius<<" 0 360 arc stroke"<<endl;
  24.     }
  25. };

  26. class Line:public Shape{
  27. private:
  28.     double x1, x2,y1, y2;
  29. public:
  30.     Line(double x1, double y1,double x2, double y2):x1(x1),y1(y1),x2(x2),y2(y2){}
  31.     void draw(ostream& f){
  32.         f<<x1<<' '<<y1<<" moveto "<<'\n'<<x2<<' '<<y2<<" lineto"<<'\n'<< "stroke " <<endl;
  33.     }
  34. };

  35. class Rect:public Shape{
  36. private:
  37.     double x, y, width, height;
  38. public:
  39.     Rect(double x, double y, double width, double height):x(x),y(y),width(width),height(height){}
  40.     void draw(ostream& f){
  41.         f<<x<<' '<<y<<" moveto "<<'\n'<<x+width<<' '<<y<<" lineto "<<'\n'<<x+width
  42.          <<' '<<y+height<<" lineto "<<'\n'<<x<<' '<<y+height<<" lineto"<<'\n'<< "closepath stroke"<<endl;
  43.     }
  44. };
  45. class Polygon:public Shape{
  46. private:
  47.     double x, y, radius,side;
  48. public:
  49.     Polygon(double x, double y, double radius, double side):x(x),y(y),radius(radius),side(side){}
  50.     void draw(ostream& f){
  51.         f<<x+radius<<' '<<y<<" moveto "<<endl;
  52.         for(int i=1; i<side; i++){
  53.             f<<x+radius*cos(2*i*PI/side)<<' '<<y+radius*sin(PI*2*i/side)<<" lineto "<<'\n';
  54.         }
  55.         f<<"closepath stroke"<<endl;

  56.     }

  57. };

  58. class FilledRect:public Shape{
  59. private:
  60.     double x, y, width,height ;
  61. public:
  62.     FilledRect(double x, double y, double width, double height)
  63.             :x(x),y(y),width(width),height(height){}
  64.     void draw(ostream& f){
  65.         f <<x << ' ' << y << " moveto " <<'\n'<< x+width
  66.           << ' ' << y<< " lineto " <<'\n'<< x + width << ' ' << y + height
  67.           << " lineto " <<'\n'<< x<< ' ' << y +height << " lineto"<<'\n'<< "closepath fill"<<endl;

  68.     }
  69. };

  70. class FilledCircle:public Shape{
  71. private:
  72.     double x, y, radius;
  73. public:
  74.     FilledCircle(double x, double y, double radius):x(x),y(y),radius(radius){}
  75.     void draw(ostream& f){
  76.         f<<x<<' '<<y<<' '<<radius
  77.          <<" 0 360 arc fill"<<endl;
  78.     }
  79. };

  80. class Drawing {
  81. private:
  82.     ofstream f;
  83.     vector<Shape*> shapes;
  84.     int r, g, b;
  85. public:
  86.     void setrgb(double r, double g, double b){
  87.         f<<r<<' '<<g<<' '<<b<<" setrgbcolor "<<endl;
  88.     }
  89.     Drawing(string filename) : f(filename.c_str()), shapes() {
  90.     }
  91.     void add( Shape* s ) {
  92.         shapes.push_back(s);
  93.     }
  94.     void draw() {
  95.         for (int i = 0; i <shapes.size(); i++)
  96.             shapes[i]->draw(f);
  97.     }

  98. };
  99. int main() {
  100.     ofstream f();
  101.     Drawing d("../test2.txt");
  102.     d.setrgb(1,0,0); // set drawing color to be bright red:  1 0 0 setrgbcolor
  103.     d.add(new FilledRect(100.0, 150.0, 200.0, 50)); // x y moveto x y lineto ... fill
  104.     d.add(new Rect(100.0, 150.0, 200.0, 50));       // x y moveto x y lineto ... stroke
  105.     for (int x = 0; x < 600; x += 100)
  106.         d.add(new FilledCircle(x,200,50.0)); // x y r 0 360 arc fill
  107.     d.setrgb(0,1,0); // the rest are green
  108.     d.add(new Circle(0,0, 100)); // 0 0 100 0 360 stroke
  109.     d.add(new Line(400,500, 600,550));
  110.     d.add(new Polygon(200,200, 50, 6));
  111.     d.draw();

  112. }
复制代码
最佳答案
2019-10-16 23:49:42
本帖最后由 superbe 于 2019-10-17 00:05 编辑

重新修改过了,试试可以吗

  1. #include <iostream>
  2. #include <fstream>
  3. #include <vector>
  4. #include <cmath>
  5. const double PI=3.141592653;
  6. using namespace std;

  7. class Shape{
  8. private:
  9.     double r, g, b;
  10.     //ofstream f;
  11. public:
  12.     void setrgb(double r, double g, double b){  //修改的函数
  13.         //f<<r<<' '<<g<<' '<<b<<" setrgbcolor "<<endl;
  14.         this->r = r;
  15.         this->g = g;
  16.         this->b = b;
  17.     }
  18.     void writergb(ostream& f){  //增加的函数
  19.         f<<r<<' '<<g<<' '<<b<<" setrgbcolor "<<endl;
  20.     }
  21.     virtual void draw(ostream& s) = 0;
  22. };

  23. class Circle:public Shape{
  24. private:
  25.     double x,y,radius;
  26. public:
  27.     Circle(double x, double y, double radius):x(x),y(y),radius(radius){}
  28.     void draw(ostream& f){
  29.         f<< x << ' ' << y <<' '<< radius <<" 0 360 arc stroke"<< endl;
  30.     }
  31. };

  32. class Line:public Shape{
  33. private:
  34.     double x1, x2,y1, y2;
  35. public:
  36.     Line(double x1, double y1,double x2, double y2):x1(x1),y1(y1),x2(x2),y2(y2){}
  37.     void draw(ostream& f){
  38.         f<<x1<<' '<<y1<<" moveto "<<'\n'<<x2<<' '<<y2<<" lineto"<<'\n'<<"stroke "<<endl;
  39.     }
  40. };

  41. class Rect:public Shape{
  42. private:
  43.     double x, y, width, height;
  44. public:
  45.     Rect(double x, double y, double width, double height):x(x),y(y),width(width),height(height){}
  46.     void draw(ostream& f){
  47.         f<<x<<' '<<y<<" moveto "<<'\n'<<x+width<<' '<<y<<" lineto "<<'\n'<<x+width
  48.          <<' '<<y+height<<" lineto "<<'\n'<<x<<' '<<y+height<<" lineto"<<'\n'<< "closepath stroke"<<endl;
  49.     }
  50. };

  51. class Polygon:public Shape{
  52. private:
  53.     double x, y, radius,side;
  54. public:
  55.     Polygon(double x, double y, double radius, double side):x(x),y(y),radius(radius),side(side){}
  56.     void draw(ostream& f){
  57.         f<<x+radius<<' '<<y<<" moveto "<<endl;
  58.         for(int i=1; i<side; i++){
  59.             f<<x+radius*cos(2*i*PI/side)<<' '<<y+radius*sin(PI*2*i/side)<<" lineto "<<'\n';
  60.         }
  61.         f<<"closepath stroke"<<endl;
  62.     }
  63. };

  64. class FilledRect:public Shape{
  65. private:
  66.     double x, y, width,height ;
  67. public:
  68.     FilledRect(double x, double y, double width, double height)
  69.             :x(x),y(y),width(width),height(height){}
  70.     void draw(ostream& f){
  71.         f <<x << ' ' << y << " moveto " <<'\n'<< x+width
  72.           << ' ' << y<< " lineto " <<'\n'<< x + width << ' ' << y + height
  73.           << " lineto " <<'\n'<< x<< ' ' << y +height << " lineto"<<'\n'<< "closepath fill"<<endl;

  74.     }
  75. };

  76. class FilledCircle:public Shape{
  77. private:
  78.     double x, y, radius;
  79. public:
  80.     FilledCircle(double x, double y, double radius):x(x),y(y),radius(radius){}
  81.     void draw(ostream& f){
  82.         f<<x<<' '<<y<<' '<<radius<<" 0 360 arc fill"<<endl;
  83.     }
  84. };

  85. class Drawing {
  86. private:
  87.     ofstream f;
  88.     vector<Shape*> shapes;
  89.     double r, g, b;
  90. public:
  91.     void setrgb(double r, double g, double b){  //修改的函数
  92.         //f<<r<<' '<<g<<' '<<b<<" setrgbcolor "<<endl;
  93.         this->r = r;
  94.         this->g = g;
  95.         this->b = b;
  96.     }
  97.     Drawing(string filename) : f(filename.c_str()), shapes() {
  98.     }
  99.     void add( Shape *s ) {  //修改的函数
  100.         s->setrgb(r, g, b);
  101.         shapes.push_back(s);
  102.     }
  103.     void draw() {    //修改的函数
  104.         for (int i = 0; i <shapes.size(); i++){
  105.             shapes[i]->writergb(f);
  106.             shapes[i]->draw(f);
  107.         }
  108.     }
  109. };

  110. int main() {   //main未改动
  111.     ofstream f();
  112.     Drawing d("../test2.txt");
  113.     d.setrgb(1,0,0); // set drawing color to be bright red:  1 0 0 setrgbcolor
  114.     d.add(new FilledRect(100.0, 150.0, 200.0, 50)); // x y moveto x y lineto ... fill
  115.     d.add(new Rect(100.0, 150.0, 200.0, 50));       // x y moveto x y lineto ... stroke
  116.     for (int x = 0; x < 600; x += 100)
  117.         d.add(new FilledCircle(x,200,50.0)); // x y r 0 360 arc fill
  118.     d.setrgb(0,1,0); // the rest are green
  119.     d.add(new Circle(0,0, 100)); // 0 0 100 0 360 stroke
  120.     d.add(new Line(400,500, 600,550));
  121.     d.add(new Polygon(200,200, 50, 6));
  122.     d.draw();

  123. }
复制代码

开头有2个设置颜色的语句,但是第二个会把第一个覆盖掉,具体的要求写在上面

开头有2个设置颜色的语句,但是第二个会把第一个覆盖掉,具体的要求写在上面
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-10-16 20:45:17 | 显示全部楼层
本帖最后由 superbe 于 2019-10-16 20:57 编辑

main里面只在最后d.draw()的时候才会输出全部图形,第一个和第二个d.setrgb之间的图形并没有输出,所以等于连续向文件中输出了两个setrgb,这样只是第二个setrgb才会对后面的图形起作用。

你可以在class Drawing里增加一个函数,用来清空shapes。
  1. void clear(){
  2.     shapes.clear();
  3. }
复制代码

在输出前几个红色的图形后,调用clear清空shapes,然后设置绿色再输出后面几个绿色图形。

main函数修改如下,为了图形不重叠,我调整了图形坐标(注释未改),根据实际情况修改吧:
  1. int main() {
  2.     //ofstream f();
  3.     Drawing d("../test2.txt");
  4.     d.setrgb(1, 0, 0); // set drawing color to be bright red:  1 0 0 setrgbcolor
  5.     d.add(new FilledRect(100.0, 150.0, 200.0, 50)); // x y moveto x y lineto ... fill
  6.     d.add(new Rect(100.0, 250.0, 200.0, 50));       // x y moveto x y lineto ... stroke
  7.     for (int x = 50; x < 650; x += 100)
  8.         d.add(new FilledCircle(x, 400, 50.0)); // x y r 0 360 arc fill
  9.     d.draw();  //增加的行
  10.     d.clear();  //增加的行
  11.     d.setrgb(0, 1, 0); // the rest are green
  12.     d.add(new Circle(400, 100, 100)); // 0 0 100 0 360 stroke
  13.     d.add(new Line(400, 500, 550, 550));
  14.     d.add(new Polygon(200, 500, 50, 6));
  15.     d.draw();
  16.     return 0;
  17. }
复制代码


最后的效果是这样的:
gsview.jpg

生成的ps文件内容如下:
ps.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-16 22:02:47 | 显示全部楼层
superbe 发表于 2019-10-16 20:45
main里面只在最后d.draw()的时候才会输出全部图形,第一个和第二个d.setrgb之间的图形并没有输出,所以等于 ...

我们的main函数是老师先写好的,老师说不可以改,请问你可以说一下不改main函数只在class中编辑的解决方法嘛?谢谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-16 23:49:42 | 显示全部楼层    本楼为最佳答案   
本帖最后由 superbe 于 2019-10-17 00:05 编辑

重新修改过了,试试可以吗

  1. #include <iostream>
  2. #include <fstream>
  3. #include <vector>
  4. #include <cmath>
  5. const double PI=3.141592653;
  6. using namespace std;

  7. class Shape{
  8. private:
  9.     double r, g, b;
  10.     //ofstream f;
  11. public:
  12.     void setrgb(double r, double g, double b){  //修改的函数
  13.         //f<<r<<' '<<g<<' '<<b<<" setrgbcolor "<<endl;
  14.         this->r = r;
  15.         this->g = g;
  16.         this->b = b;
  17.     }
  18.     void writergb(ostream& f){  //增加的函数
  19.         f<<r<<' '<<g<<' '<<b<<" setrgbcolor "<<endl;
  20.     }
  21.     virtual void draw(ostream& s) = 0;
  22. };

  23. class Circle:public Shape{
  24. private:
  25.     double x,y,radius;
  26. public:
  27.     Circle(double x, double y, double radius):x(x),y(y),radius(radius){}
  28.     void draw(ostream& f){
  29.         f<< x << ' ' << y <<' '<< radius <<" 0 360 arc stroke"<< endl;
  30.     }
  31. };

  32. class Line:public Shape{
  33. private:
  34.     double x1, x2,y1, y2;
  35. public:
  36.     Line(double x1, double y1,double x2, double y2):x1(x1),y1(y1),x2(x2),y2(y2){}
  37.     void draw(ostream& f){
  38.         f<<x1<<' '<<y1<<" moveto "<<'\n'<<x2<<' '<<y2<<" lineto"<<'\n'<<"stroke "<<endl;
  39.     }
  40. };

  41. class Rect:public Shape{
  42. private:
  43.     double x, y, width, height;
  44. public:
  45.     Rect(double x, double y, double width, double height):x(x),y(y),width(width),height(height){}
  46.     void draw(ostream& f){
  47.         f<<x<<' '<<y<<" moveto "<<'\n'<<x+width<<' '<<y<<" lineto "<<'\n'<<x+width
  48.          <<' '<<y+height<<" lineto "<<'\n'<<x<<' '<<y+height<<" lineto"<<'\n'<< "closepath stroke"<<endl;
  49.     }
  50. };

  51. class Polygon:public Shape{
  52. private:
  53.     double x, y, radius,side;
  54. public:
  55.     Polygon(double x, double y, double radius, double side):x(x),y(y),radius(radius),side(side){}
  56.     void draw(ostream& f){
  57.         f<<x+radius<<' '<<y<<" moveto "<<endl;
  58.         for(int i=1; i<side; i++){
  59.             f<<x+radius*cos(2*i*PI/side)<<' '<<y+radius*sin(PI*2*i/side)<<" lineto "<<'\n';
  60.         }
  61.         f<<"closepath stroke"<<endl;
  62.     }
  63. };

  64. class FilledRect:public Shape{
  65. private:
  66.     double x, y, width,height ;
  67. public:
  68.     FilledRect(double x, double y, double width, double height)
  69.             :x(x),y(y),width(width),height(height){}
  70.     void draw(ostream& f){
  71.         f <<x << ' ' << y << " moveto " <<'\n'<< x+width
  72.           << ' ' << y<< " lineto " <<'\n'<< x + width << ' ' << y + height
  73.           << " lineto " <<'\n'<< x<< ' ' << y +height << " lineto"<<'\n'<< "closepath fill"<<endl;

  74.     }
  75. };

  76. class FilledCircle:public Shape{
  77. private:
  78.     double x, y, radius;
  79. public:
  80.     FilledCircle(double x, double y, double radius):x(x),y(y),radius(radius){}
  81.     void draw(ostream& f){
  82.         f<<x<<' '<<y<<' '<<radius<<" 0 360 arc fill"<<endl;
  83.     }
  84. };

  85. class Drawing {
  86. private:
  87.     ofstream f;
  88.     vector<Shape*> shapes;
  89.     double r, g, b;
  90. public:
  91.     void setrgb(double r, double g, double b){  //修改的函数
  92.         //f<<r<<' '<<g<<' '<<b<<" setrgbcolor "<<endl;
  93.         this->r = r;
  94.         this->g = g;
  95.         this->b = b;
  96.     }
  97.     Drawing(string filename) : f(filename.c_str()), shapes() {
  98.     }
  99.     void add( Shape *s ) {  //修改的函数
  100.         s->setrgb(r, g, b);
  101.         shapes.push_back(s);
  102.     }
  103.     void draw() {    //修改的函数
  104.         for (int i = 0; i <shapes.size(); i++){
  105.             shapes[i]->writergb(f);
  106.             shapes[i]->draw(f);
  107.         }
  108.     }
  109. };

  110. int main() {   //main未改动
  111.     ofstream f();
  112.     Drawing d("../test2.txt");
  113.     d.setrgb(1,0,0); // set drawing color to be bright red:  1 0 0 setrgbcolor
  114.     d.add(new FilledRect(100.0, 150.0, 200.0, 50)); // x y moveto x y lineto ... fill
  115.     d.add(new Rect(100.0, 150.0, 200.0, 50));       // x y moveto x y lineto ... stroke
  116.     for (int x = 0; x < 600; x += 100)
  117.         d.add(new FilledCircle(x,200,50.0)); // x y r 0 360 arc fill
  118.     d.setrgb(0,1,0); // the rest are green
  119.     d.add(new Circle(0,0, 100)); // 0 0 100 0 360 stroke
  120.     d.add(new Line(400,500, 600,550));
  121.     d.add(new Polygon(200,200, 50, 6));
  122.     d.draw();

  123. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-17 00:13:27 | 显示全部楼层
解决思路是这样的:
调用d.setrgb时把rgb值存储在d中,以后添加每个图形时把rgb值设置到图形中。
最后输出时,先调用图形的writergb将其rgb值写到文件,接着再调用该图形的draw方法写入画图的命令。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-17 02:50:52 | 显示全部楼层
superbe 发表于 2019-10-17 00:13
解决思路是这样的:
调用d.setrgb时把rgb值存储在d中,以后添加每个图形时把rgb值设置到图形中。
最后输 ...

奥,我明白啦,谢谢你,你真厉害哇~~!我要是有你学的这么好就好了-。-
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-18 21:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表