2 * psychlops_g_shape.cpp
3 * Psychlops Standard Library (Universal)
5 * Last Modified 2005/10/05 by Kenchi HOSOKAWA
6 * (C) 2005 Kenchi HOSOKAWA, Kazushi MARUYA, Takao SATO
9 #include "psychlops_g_fundamental.h"
10 #include "psychlops_g_color.h"
11 #include "psychlops_g_shape.h"
13 #include "psychlops_g_canvas.h"
14 #include "psychlops_g_image.h"
22 // Shape& Shape::draw() { draw(*Drawable::prime); return *this; };
30 Stroke::Stroke(const Color col, const double wid, const Pattern pat) {
36 Stroke& Stroke::set(const Color col, const double wid, const Pattern pat) {
43 const Stroke Stroke::null_line(Color::null_color, 0, SOLID);
44 const Stroke Stroke::hair_line(Color(0.75), 1, SOLID);
46 Shape::Shape() : fill(Color::null_color), stroke(Stroke::null_line) {
48 Shape& Shape::draw_base(Drawable &target) {
49 if(fill.getA()!=0) draw(fill, target);
50 if(stroke.width!=0) draw(stroke, target);
53 #if !defined(_MSC_VER)
54 Shape& Shape::draw(Drawable &target) {
55 return draw_base(target);
63 //////// Rectangle ////////
65 template <typename X> inline void Rectangle::correctInversion(X &l, X &t, X &r, X &b) {
67 if(l>r) { tmp=l; l=r; r=tmp; }
68 if(t>b) { tmp=t; t=b; b=tmp; }
70 inline void Rectangle::setbypix(double l, double t, double r, double b) {
76 inline void Rectangle::setbypix(double width, double height) {
77 setbypix(0.0, 0.0, width-1, height-1);
79 inline void Rectangle::set(double size) {
80 setbypix(0.0, 0.0, size-1, size-1);
84 // Rectangle::Rectangle() : left(0.0), top(0.0), right(0.0), bottom(0.0), color(0.0, 0.0, 0.0) {
85 Rectangle::Rectangle() {}
86 Rectangle::Rectangle(double l, double t, double r, double b) {
87 if(r-l<=0 || b-t<=0) throw Exception(typeid(*this), "SIZE ERROR", "Width and Height must be defined as positive value.");
90 Rectangle::Rectangle(double width, double height) {
91 if(width<=0 || height<=0) throw Exception(typeid(*this), "SIZE ERROR", "Width and Height must be defined as positive value.");
95 Rectangle& Rectangle::set(const Rectangle &r) {
96 set(r.left, r.top, r.right, r.bottom);
99 Rectangle& Rectangle::set(const Point &po1, const Point &po2) {
100 double l=po1.x, t=po1.y, r=po2.x, b=po2.y;
101 correctInversion(l,t,r,b);
102 setbypix(l, t, r, b);
105 Rectangle& Rectangle::set(double l, double t, double r, double b) {
106 correctInversion(l,t,r,b);
107 setbypix(l, t, r, b);
110 Rectangle& Rectangle::set(double width, double height) {
111 setbypix(width, height);
114 Rectangle Rectangle::dup() {
117 Rectangle& Rectangle::resize(double width, double height) {
118 Point po = getCenter();
119 setbypix(width, height);
123 Rectangle& Rectangle::locate(const Point &p) {
124 return locate(p.x, p.y);
126 Rectangle& Rectangle::locate(double x, double y) {
127 double w = getWidth(), h = getHeight();
128 set(x,y,x+w-1,y+h-1);
131 Rectangle& Rectangle::alignLeft(const double lef) {
\r
132 return move_to(lef, getTop(), getDatum().z);
\r
134 Rectangle& Rectangle::alignTop(const double to_) {
\r
135 return move_to(getLeft(), to_, getDatum().z);
\r
137 Rectangle& Rectangle::alignRight(const double rig) {
\r
138 return move_to(rig-getWidth(), getTop(), getDatum().z);
\r
140 Rectangle& Rectangle::alignBottom(const double bot) {
\r
141 return move_to(getLeft(), bot-getHeight(), getDatum().z);
\r
145 Rectangle& Rectangle::setDatum(const Point& p) {
146 return move_to(p.x, p.y, p.z);
148 Rectangle& Rectangle::move_to(const double x, const double y, const double z) {
149 //int Hoffset = x-getHcenter(), Voffset=getVcenter();
150 //return shift(Hoffset, Voffset);
152 r = x + (getWidth()-1),
154 b = y + (getHeight()-1);
158 Rectangle& Rectangle::centering(const double x, const double y, const double z) {
159 //int Hoffset = x-getHcenter(), Voffset=getVcenter();
160 //return shift(Hoffset, Voffset);
161 double l = x - (getWidth()-1)/2.0,
162 r = x + (getWidth()-1)/2.0,
163 t = y - (getHeight()-1)/2.0,
164 b = y + (getHeight()-1)/2.0;
168 Rectangle& Rectangle::centering(const Drawable& target) {
169 return centering(target.getCenter());
171 Rectangle& Rectangle::centering(const Figure &fig) {
172 return centering(fig.getDatum());
174 Rectangle& Rectangle::centering(const Point &po) {
175 return centering(po.x, po.y);
177 Rectangle& Rectangle::shift(const double h, const double v, const double d) {
185 Rectangle& Rectangle::draw(Drawable &target) {
186 Shape::draw_base(target);
189 Rectangle& Rectangle::draw(const Color &col, Drawable &target) {
190 Drawable::prime->rect(*this, col);
193 Rectangle& Rectangle::draw(const Stroke &strk, Drawable &target) {
194 Drawable::prime->rect(*this, strk);
198 Rectangle& Rectangle::display() {
201 Rectangle& Rectangle::display(const Color &col) {
206 void Rectangle::clipped_by(const Rectangle &source) {
207 double t=top, l=left, b=bottom, r=right;
208 if(top < source.top) { t = source.top; }
209 if(left < source.left) { l = source.left; }
210 if(bottom > source.bottom) { b = source.bottom; }
211 if(right > source.right) { r = source.right; }
215 throw Exception(typeid(*this), "SIZE ERROR", "Cripped rectangle is null.");
218 void Rectangle::clip(Rectangle &target) {
219 double t=top, l=left, b=bottom, r=right;
220 if(top < target.top) { t = target.top; }
221 if(left < target.left) { l = target.left; }
222 if(bottom > target.bottom) { b = target.bottom; }
223 if(right > target.right) { r = target.right; }
227 throw Exception(typeid(*this), "SIZE ERROR", "Cripped rectangle is null.");
230 // obsolete: misspelled
231 void Rectangle::cripped(const Rectangle &source) { clipped_by(source); }
232 void Rectangle::crip(Rectangle &target) { clip(target); }
234 bool Rectangle::include(double x, double y) const {
235 return (top <= y) && (left <= x) && (bottom >= y) && (right >= x);
237 bool Rectangle::include(const Point &p) const {
238 return (top <= p.y) && (left <= p.x) && (bottom >= p.y) && (right >= p.x);
240 bool Rectangle::include(const Rectangle &rect) const {
241 return (top <= rect.top) && (left <= rect.left) && (bottom >= rect.bottom) && (right >= rect.right);
245 void Rectangle::setColor(Color col) {
249 double Rectangle::getWidth() const { return right>left ? right-left+1 : left-right+1; }
250 double Rectangle::getHeight() const { return bottom>top ? bottom-top+1 : top-bottom+1; }
251 const Point Rectangle::getDatum() const {
252 //Point po(getHcenter(), getVcenter());
\r
256 const Point Rectangle::getCenter() const {
257 Point po(getHcenter(), getVcenter());
260 double Rectangle::getHcenter() const { return (double)( (right + left) / 2.0 ); }
261 double Rectangle::getVcenter() const { return (double)( (bottom + top) / 2.0 ); }
262 double Rectangle::getTop() const { return top; }
263 double Rectangle::getLeft() const { return left; }
264 double Rectangle::getBottom() const { return bottom; }
265 double Rectangle::getRight() const { return right; }
270 //////// Line ////////
273 Line::Line(const double x1, const double y1, const double x2, const double y2) : end(Point(x2, y2)) {
278 Line::Line(const Point &dbegin, const Point &dend) : end(dend) {
281 Line& Line::set(const double x1, const double y1, const double x2, const double y2) {
290 Line& Line::set(const Point &dbegin, const Point &dend) {
296 Line& Line::setDatum(const Point &p) {
297 Point vec = end-datum;
299 end = (Point)p + vec;
302 Line& Line::setStart(const Point &p) {
306 Line& Line::centering(const Point &p) {
308 datum.set(p.x-v.x, p.y-v.y, p.z-v.y);
309 end.set(p.x+v.x, p.y+v.y, p.z+v.y);
312 Line& Line::shift(const double x, const double y, const double z) {
\r
321 Line& Line::draw(Drawable &target) {
322 target.line(*this, stroke);
325 Line& Line::draw(const Color &col, Drawable &target) {
326 target.line(*this, col);
329 Line& Line::draw(const Stroke &strk, Drawable &target) {
330 target.line(*this, strk);
334 Point Line::getEnd() const {
339 //////// Ellipse ////////
341 Ellipse::Ellipse() : radius(0), v_radius(0), sector_begin(0), sector_end(0) {}
342 Ellipse::Ellipse(const double d_radius, const double d_v_radius, const Point& d_datum) : sector_begin(0), sector_end(0) { set(d_radius, d_v_radius, d_datum); }
343 Ellipse::Ellipse(const Rectangle& rect) : radius(0), v_radius(0), sector_begin(0), sector_end(0) { set(rect); }
344 Ellipse::~Ellipse(){}
345 Ellipse& Ellipse::set(const double d_radius, const double d_v_radius, const Point& d_datum) {
348 v_radius = (d_v_radius<0) ? d_radius : d_v_radius;
351 Ellipse& Ellipse::set(const Rectangle& rect) {
352 datum = rect.getDatum();
353 radius = rect.getWidth();
354 v_radius = rect.getHeight();
357 Ellipse& Ellipse::resize(double width, double height)
\r
363 Ellipse& Ellipse::centering(const Point &p) {
367 Ellipse& Ellipse::draw(Drawable &target) {
368 Shape::draw_base(target);
371 Ellipse& Ellipse::draw(const Color &col, Drawable &target){
372 target.ellipse(*this, col);
375 Ellipse& Ellipse::draw(const Stroke &strk, Drawable &target) {
376 target.ellipse(*this, strk);
380 Ellipse& Ellipse::centering(const Figure& fig) { centering(fig.getDatum()); return *this; }
381 Ellipse& Ellipse::centering(const Drawable &target) { centering(target.getCenter()); return *this; }
382 Ellipse& Ellipse::centering(const double x, const double y, const double z) { centering(Point(x,y,z)); return *this; }
383 Ellipse& Ellipse::shift(const double x, const double y, const double z) { Point n=getDatum(); n=n+Point(x,y,z); setDatum(n); return *this; }
385 //////// Polygon ////////
387 Polygon::Polygon() {}
388 bool Polygon::empty() const {
389 return vertices.empty();
391 Polygon& Polygon::append(const Point& p) {
392 vertices.push_back(p);
395 Polygon& Polygon::append(const double x, const double y, const double z) { return append(Point(x,y,z)); }
396 Polygon& Polygon::centering(const Point &p) {
400 Polygon& Polygon::draw(Drawable& target) {
401 Shape::draw_base(target);
405 Polygon& Polygon::append(const Point& p, const Color& col) {
409 vertices.push_back(v);
413 // Polygon& Polygon::append(const double x, const double y, const double z, const Color& col) { return append(Point(x, y, z), col); }
414 // Polygon& Polygon::append(const double x, const double y, const Color& col) { return add(x,y,0,col); }
416 Polygon& Polygon::draw(const Color& col, Drawable& target) {
417 target.polygon(*this, col);
420 Polygon& Polygon::draw(const Stroke& strk, Drawable &target) {
421 target.polygon(*this, strk);
425 Polygon& Polygon::centering(const Figure& fig) { centering(fig.getDatum()); return *this; }
426 Polygon& Polygon::centering(const Drawable &target) { centering(target.getCenter()); return *this; }
427 Polygon& Polygon::centering(const double x, const double y, const double z) { centering(Point(x,y,z)); return *this; }
428 Polygon& Polygon::shift(const double x, const double y, const double z) { Point n=getDatum(); n=n+Point(x,y,z); setDatum(n); return *this; }
430 //////// PolyLine ////////
432 PolyLine::PolyLine() {}
433 bool PolyLine::empty() const {
434 return vertices.empty();
436 PolyLine& PolyLine::append(const Point& p) {
437 vertices.push_back(p);
440 PolyLine& PolyLine::append(const double x, const double y, const double z) { return append(Point(x,y,z)); }
441 PolyLine& PolyLine::centering(const Point &p) {
445 PolyLine& PolyLine::draw(Drawable& target) {
446 Shape::draw_base(target);
449 PolyLine& PolyLine::draw(const Color& col, Drawable& target) {
450 target.polyline(*this, col);
453 PolyLine& PolyLine::draw(const Stroke& strk, Drawable &target) {
454 target.polyline(*this, strk);
458 PolyLine& PolyLine::centering(const Figure& fig) { centering(fig.getDatum()); return *this; }
459 PolyLine& PolyLine::centering(const Drawable &target) { centering(target.getCenter()); return *this; }
460 PolyLine& PolyLine::centering(const double x, const double y, const double z) { centering(Point(x,y,z)); return *this; }
461 PolyLine& PolyLine::shift(const double x, const double y, const double z) { Point n=getDatum(); n=n+Point(x,y,z); setDatum(n); return *this; }
463 } /* <- namespace Psycholops */