canvas.cpp
来自「C++&datastructure书籍源码,以前外教提供现在与大家共享」· C++ 代码 · 共 1,412 行 · 第 1/2 页
CPP
1,412 行
{
return string("ellipse ") + bbox().tostring();
}
RectangleShape::RectangleShape(const Point& p, double w, double h, color c)
: myPoint(p),
myWidth(w),
myHeight(h),
myColor(c)
{
// note: + 1 ?? is because of how rectangles are drawn in
// graphics.h, they go from xul,yul to xlr-1,ylr-1
}
void RectangleShape::draw(AnimatedCanvas& c)
{
c.SetColor(myColor);
c.DrawRectangle(myPoint.x,myPoint.y,
myPoint.x + myWidth,
myPoint.y + myHeight);
}
Box RectangleShape::bbox() const
{
return Box(myPoint.x, myPoint.y,
myPoint.x + myWidth, myPoint.y + myHeight);
}
Shape * RectangleShape::clone()
{
RectangleShape * r = new RectangleShape(myPoint,myWidth,myHeight,myColor);
return r;
}
void RectangleShape::setLocation(const Point& p)
{
myPoint = p;
}
Point RectangleShape::getLocation() const
{
return myPoint;
}
string RectangleShape::tostring() const
{
return string("rectangle ") + bbox().tostring();
}
TriangleShape::TriangleShape(const Point& p1, const Point& p2, const Point& p3,
color c)
{
tvector<Point> p(3);
p[0] = p1;
p[1] = p2;
p[2] = p3;
myShape = new PolygonShape(p,3,c);
myShape->setLocation(myShape->getLocation());
}
void TriangleShape::setLocation(const Point& p)
{
myShape->setLocation(p);
}
Point TriangleShape::getLocation() const
{
return myShape->getLocation();
}
TriangleShape::TriangleShape(const TriangleShape& ts)
{
myShape = dynamic_cast<PolygonShape *> (ts.myShape->clone());
myShape->setLocation(myShape->getLocation());
}
const TriangleShape& TriangleShape::operator =(const TriangleShape& ts)
{
if (this != &ts)
{
// delete myShape;
myShape = dynamic_cast<PolygonShape *> (ts.myShape->clone());
}
return *this;
}
TriangleShape::~TriangleShape()
{
// delete myShape;
myShape = 0;
}
void TriangleShape::draw(AnimatedCanvas& c)
{
myShape->draw(c);
}
Box TriangleShape::bbox() const
{
return myShape->bbox();
}
Shape * TriangleShape::clone()
{
return new TriangleShape(*this);
}
string TriangleShape::tostring() const
{
return string("triangle ") + bbox().tostring();
}
PolygonShape::PolygonShape(const tvector<Point>& a, int numPoints, color c)
: myXdeltas(numPoints),
myYdeltas(numPoints),
myColor(c)
{
Point minp = a[0];
Point maxp = a[0];
double miny = a[0].y;
double maxy = a[0].y;
int k;
for(k=1; k < numPoints; k++)
{
minp = min(minp,a[k]);
maxp = max(maxp,a[k]);
miny = min(miny,a[k].y);
maxy = max(maxy,a[k].y);
}
myMin = myPoint = minp;
for(k=0; k < numPoints; k++)
{
myXdeltas[k] = a[k].x - minp.x;
myYdeltas[k] = a[k].y - minp.y;
}
// create bounding box
myBox = Box(minp.x,miny,maxp.x,maxy);
myPoint = myBox.getUL();
}
void PolygonShape::setLocation(const Point& p)
{
double dx = p.x - myPoint.x;
double dy = p.y - myPoint.y;
myPoint = p;
//myMin.x += dx;
//myMin.y += dy;
int k;
for(k=0; k < myXdeltas.size(); k++)
{
myXdeltas[k] += dx;
myYdeltas[k] += dy;
}
Point ul = myBox.getUL();
Point lr = myBox.getLR();
// myBox = Box(ul.x + dx, ul.y + dy, lr.x + dx, lr.y + dy);
myBox = Box(myPoint.x, myPoint.y, myPoint.x + myBox.width(), myPoint.y + myBox.height());
}
Point PolygonShape::getLocation() const
{
return myPoint;
// return myBox.getUL();
}
void PolygonShape::draw(AnimatedCanvas& c)
{
tvector<Point> p(myXdeltas.capacity());
//static int * xa = new int[myXdeltas.length()];
//static int * ya = new int[myXdeltas.length()];
int k;
int len = myXdeltas.capacity();
for(k=0; k < len; k++)
{
// xa[k] = myMin.x + myXdeltas[k];
// ya[k] = myMin.y + myYdeltas[k];
p[k].x = myMin.x + myXdeltas[k];
p[k].y = myMin.y + myYdeltas[k];
}
c.SetColor(myColor);
c.DrawPolygon(p,len);
}
Box PolygonShape::bbox() const
{
return myBox;
}
Shape * PolygonShape::clone()
{
tvector<Point> p(myXdeltas.size());
int k;
for(k=0; k < myXdeltas.size(); k++)
{
p[k] = Point(myMin.x + myXdeltas[k], myMin.y + myYdeltas[k]);
}
PolygonShape * ps = new PolygonShape(p, myXdeltas.size(),myColor);
return ps;
}
string PolygonShape::tostring() const
{
return string("polygon ") + bbox().tostring();
}
ImageShape::ImageShape(const Point& p, const string& filename,double scale)
: myPoint(p),
myScale(scale)
{
ifstream in(filename.c_str());
if (in.fail())
{
cerr << "could not access " << filename << "in ImageShape" << endl;
exit(1);
}
in.close();
myImage = new image((char *)filename.c_str(),JPEG);
}
ImageShape::ImageShape(const ImageShape& is)
: myPoint(is.getLocation()),
myImage(is.myImage),
myScale(is.myScale)
{
}
void ImageShape::draw(AnimatedCanvas& c)
{
c.DrawImage(*myImage,myPoint.x,myPoint.y, myScale);
}
Box ImageShape::bbox() const
{
return Box(myPoint.x,
myPoint.y,
myPoint.x + myImage->GetWidth()*myScale,
myPoint.y + myImage->GetHeight()*myScale);
}
Shape * ImageShape::clone()
{
ImageShape * im = new ImageShape(*this);
return im;
}
void ImageShape::setLocation(const Point& p)
{
myPoint = p;
}
Point ImageShape::getLocation() const
{
return myPoint;
}
string ImageShape::tostring() const
{
return string("image ") + bbox().tostring();
}
TextShape::TextShape( const Point& p, const string& s, color c)
: myPoint(p),
myString(s),
myColor(c),
myBox(p,Point(p.x+s.length()*4,p.y+5)),
myInitialized(false)
{
// to get real box dimensions we need a canvas
// so this is a gross approximation
}
void TextShape::changeText(const string& s)
{
myString = s;
myInitialized = false;
}
void TextShape::draw(AnimatedCanvas& c)
{
if (! myInitialized)
{
int w,h;
c.GetStringSize(w,h,myString.c_str());
myBox = Box(myPoint.x,myPoint.y,
myPoint.x+w, myPoint.y+h);
myInitialized = true;
}
c.SetColor(myColor),
c.DrawString(myString,myPoint.x,myPoint.y);
}
Box TextShape::bbox() const
{
return myBox;
}
Shape * TextShape::clone()
{
TextShape * t = new TextShape(myPoint,myString,myColor);
return t;
}
void TextShape::setLocation(const Point& p)
{
myPoint = p;
}
Point TextShape::getLocation() const
{
return myPoint;
}
string TextShape::tostring() const
{
return string("text ") + myString + " " + bbox().tostring();
}
Mover::Mover(Shape& cs)
: Shape(),
myShape(&cs)
{
}
void Mover::draw(AnimatedCanvas& c)
{
myShape->draw(c);
}
Box Mover::bbox() const
{
return myShape->bbox();
}
void Mover::moveTo(const Point& p)
{
myShape->setLocation(p);
}
void Mover::moveBy(double dx, double dy)
{
Point p = myShape->getLocation();
p.x += dx;
p.y += dy;
myShape->setLocation(p);
}
Shape * Mover::clone()
{
return myShape->clone();
}
void Mover::setLocation(const Point& p)
{
myShape->setLocation(p);
}
Point Mover::getLocation() const
{
return myShape->getLocation();
}
CompositeShape::CompositeShape()
: myShapes(),
myBox(0,0,0,0)
{
}
void CompositeShape::draw(AnimatedCanvas& c)
{
int k;
for(k=0; k < myShapes.size(); k++)
{
myShapes[k]->draw(c);
}
}
void CompositeShape::add(Shape& sh)
{
add(sh.clone());
}
void CompositeShape::add(Shape* sh)
{
myShapes.push_back(sh);
if (myShapes.size() == 1)
{
myBox = sh->bbox();
myPoint = sh->bbox().getUL(); // setLocation(sh->bbox().getUL());
}
else
{
myBox += sh->bbox();
// myPoint = min(getLocation(),sh->bbox().getUL());
myPoint = myBox.getUL();
}
}
Point CompositeShape::getLocation() const
{
return myPoint;
}
void CompositeShape::setLocation(const Point& p)
{
Point old = getLocation();
double dx = p.x - old.x;
double dy = p.y - old.y;
for(int k=0; k < myShapes.size(); k++)
{
old = myShapes[k]->getLocation();
old.x += dx;
old.y += dy;
myShapes[k]->setLocation(old);
}
myPoint = p;
}
Box CompositeShape::bbox() const
{
return Box(myPoint.x,myPoint.y,
myPoint.x + myBox.width(), myPoint.y + myBox.height());
}
Shape* CompositeShape::clone()
{
CompositeShape * c = new CompositeShape;
int k;
for(k=0; k < myShapes.size(); k++)
{
Shape * s = myShapes[k]->clone();
if (s != 0)
{
c->add(s);
}
}
return c;
}
string CompositeShape::tostring() const
{
string s = string("composite ") + bbox().tostring();
int k;
for(k=0; k < myShapes.size(); k++)
{
s += myShapes[k]->tostring();
}
return s;
}
Bouncer::Bouncer(Shape * cs, double angle, double v)
: Shape(),
myShape(cs),
myAngle(angle),
myVelocity(v)
{
}
Bouncer::Bouncer(Shape& cs, double angle, double v)
: Shape(),
myShape(cs.clone()),
myAngle(angle),
myVelocity(v)
{
}
Bouncer::Bouncer(const Bouncer& b)
: Shape(),
myShape(b.myShape->clone()),
myAngle(b.myAngle),
myVelocity(b.myVelocity)
{
}
Shape * Bouncer::clone()
{
return new Bouncer(*this);
}
void Bouncer::updatetop(AnimatedCanvas& c, Point& p)
{
myAngle = 2*PI - myAngle;
p.y -= bbox().getUL().y;
}
void Bouncer::updatebottom(AnimatedCanvas& c, Point& p)
{
myAngle = 2*PI - myAngle;
p.y += c.height() - bbox().getLR().y;
}
void Bouncer::updateleft(AnimatedCanvas& c, Point& p)
{
myAngle = PI - myAngle;
p.x -= bbox().getUL().x;
}
void Bouncer::updateright(AnimatedCanvas& c, Point& p)
{
myAngle = PI - myAngle;
p.x += c.width() - bbox().getLR().x;
}
void Bouncer::update(AnimatedCanvas& c)
{
Box b = bbox();
Point p = myShape->getLocation();
Point newP = p;
double xchange = myVelocity*cos(myAngle);
double ychange = myVelocity*sin(myAngle);
bool didChangeX = false,didChangeY=false;
if (b.getUL().x + xchange < 0)
{
updateleft(c,p);
didChangeX = true;
}
else if (b.getLR().x + xchange > c.width())
{
updateright(c,p);
didChangeX = true;
}
else if (b.getUL().y + ychange < 0)
{
updatetop(c,p);
didChangeY = true;
}
else if (b.getLR().y + ychange > c.height())
{
updatebottom(c,p);
didChangeY = true;
}
else
{ p.x += xchange;
p.y += ychange;
}
setLocation(p);
}
void Bouncer::draw(AnimatedCanvas& c)
{
update(c);
myShape->draw(c);
// c.DrawRectangle(bbox().getUL(),bbox().getLR());
}
Box Bouncer::bbox() const
{
return myShape->bbox();
}
void Bouncer::setLocation(const Point& p)
{
myShape->setLocation(p);
}
Point Bouncer::getLocation() const
{
return myShape->getLocation();
}
double Bouncer::getAngle() const
{
return myAngle;
}
double Bouncer::getVelocity() const
{
return myVelocity;
}
Mouseable::~Mouseable()
{
}
Keyable::~Keyable()
{
}
MKAdapter::MKAdapter()
{
}
void MKAdapter::processClick(const Point& p, AnimatedCanvas& c)
{
}
void MKAdapter::processKey(const Key& k, AnimatedCanvas& c)
{
}
CanvasAble::~CanvasAble()
{
}
EmptyShape::EmptyShape()
{
}
void EmptyShape::draw(AnimatedCanvas& c)
{
// do nothing
}
Box EmptyShape::bbox() const
{
return Box(Point(0,0),Point(0,0));
}
Shape * EmptyShape::clone()
{
return this;
}
void EmptyShape::setLocation(const Point& p)
{
}
Point EmptyShape::getLocation() const
{
return Point(0,0);
}
PrintWatcher::PrintWatcher(const Key& key)
: myKey(key)
{
}
void PrintWatcher::processKey(const Key& key, AnimatedCanvas& c)
{
if (key == myKey) c.Print();
}
Button::Button(const string& label)
: myLabel(label)
{
myShape = new TextShape(Point(0,0),label,CanvasColor::DARKBLUE);
}
Button::Button(const string& label,const color& c)
: myLabel(label)
{
myShape = new TextShape(Point(0,0),label,c);
}
void Button::draw(AnimatedCanvas& c)
{
c.SetColor(CanvasColor::KHAKI);
Point p = getLocation();
c.DrawRectangle(p.x,c.ycoord(p.y+1),p.x + bbox().width()-1,
c.ycoord(p.y + bbox().height() - 1));
myShape->draw(c);
}
void Button::setLocation(const Point& p)
{
myShape->setLocation(p);
}
Box Button::bbox() const
{
return myShape->bbox();
}
Point Button::getLocation() const
{
return myShape->getLocation();
}
void Button::execute(AnimatedCanvas& c)
{
}
void Button::processClick(const Point& p, AnimatedCanvas& c)
{
if (contains(p))
{
execute(c);
}
}
Shape * Button::clone()
{
return this;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?