00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00033
00034 #ifndef GROOVX_GFX_LINESTRIP_CC_UTC20050626084024_DEFINED
00035 #define GROOVX_GFX_LINESTRIP_CC_UTC20050626084024_DEFINED
00036
00037 #include "linestrip.h"
00038
00039 #include "geom/bezier4.h"
00040 #include "geom/vec3.h"
00041
00042 #include "gfx/canvas.h"
00043
00044 #include "rutz/error.h"
00045
00046 #include "rutz/trace.h"
00047 #include "rutz/debug.h"
00048 GVX_DBG_REGISTER
00049
00050 using geom::vec2d;
00051 using geom::vec3d;
00052
00053 Gfx::LineStrip::LineStrip() :
00054 canvas(0),
00055 pts(0),
00056 width(1.0),
00057 join(false),
00058 loop(false)
00059 {
00060 GVX_TRACE("Gfx::LineStrip::LineStrip");
00061 }
00062
00063 void Gfx::LineStrip::lineJoin(bool doJoin)
00064 {
00065 GVX_TRACE("Gfx::LineStrip::lineJoin");
00066 join = doJoin;
00067 }
00068
00069 void Gfx::LineStrip::closeLoop(bool doClose)
00070 {
00071 GVX_TRACE("Gfx::LineStrip::closeLoop");
00072 loop = doClose;
00073 }
00074
00075 void Gfx::LineStrip::begin(Gfx::Canvas& c, double w)
00076 {
00077 GVX_TRACE("Gfx::LineStrip::begin");
00078
00079 if (pts.size() != 0)
00080 {
00081 throw rutz::error("LineStrip::end() not called before LineStrip::begin()", SRC_POS);
00082 }
00083
00084 GVX_ASSERT(canvas == 0);
00085
00086 canvas = &c;
00087 width = w;
00088 }
00089
00090 void Gfx::LineStrip::vertex(const vec2d& pt)
00091 {
00092 GVX_TRACE("Gfx::LineStrip::vertex");
00093 pts.push_back(pt);
00094 }
00095
00096 void Gfx::LineStrip::drawBezier4(const vec3d& p1,
00097 const vec3d& p2,
00098 const vec3d& p3,
00099 const vec3d& p4,
00100 unsigned int subdivisions,
00101 unsigned int start)
00102 {
00103 GVX_TRACE("Gfx::LineStrip::drawBezier4");
00104 geom::bezier4 xb(p1.x(), p2.x(), p3.x(), p4.x());
00105 geom::bezier4 yb(p1.y(), p2.y(), p3.y(), p4.y());
00106
00107
00108 for (unsigned int i = start; i < subdivisions; ++i)
00109 {
00110 double u = double(i) / double(subdivisions - 1);
00111 this->vertex(vec2d(xb.eval(u), yb.eval(u)));
00112 }
00113 }
00114
00115 void Gfx::LineStrip::end()
00116 {
00117 GVX_TRACE("Gfx::LineStrip::end");
00118
00119 if (pts.size() == 0) return;
00120
00121 GVX_ASSERT(canvas != 0);
00122
00123 if (join)
00124 drawJoinedLineStrip();
00125 else
00126 drawSimpleLineStrip();
00127
00128 canvas = 0;
00129 pts.clear();
00130 }
00131
00132 void Gfx::LineStrip::drawSimpleLineStrip()
00133 {
00134 GVX_TRACE("Gfx::LineStrip::drawSimpleLineStrip");
00135 if (loop)
00136 canvas->beginLineLoop();
00137 else
00138 canvas->beginLineStrip();
00139 for (unsigned int i = 0; i < pts.size(); ++i)
00140 {
00141 canvas->vertex2(pts[i]);
00142 }
00143 canvas->end();
00144 }
00145
00146 namespace
00147 {
00148
00149
00150
00151
00152
00153 vec2d joinedNormal(const vec2d& d1, const vec2d& d2)
00154 {
00155 const vec2d n1 = normal_to(d1);
00156 const vec2d n2 = normal_to(d2);
00157
00158 double c = 0.0;
00159 if (d1.x()+d2.x() != 0.0) { c = (n2.x() - n1.x()) / (d1.x() + d2.x()); }
00160 else if (d1.y()+d2.y() != 0.0) { c = (n2.y() - n1.y()) / (d1.y() + d2.y()); }
00161
00162 return vec2d(n2 - d2 * c);
00163 }
00164 }
00165
00166 void Gfx::LineStrip::drawJoinedLineStrip()
00167 {
00168 GVX_TRACE("Gfx::LineStrip::drawJoinedLineStrip");
00169 canvas->beginQuadStrip();
00170
00171 vec2d d1;
00172 vec2d d2;
00173
00174 vec2d start_pt1;
00175 vec2d start_pt2;
00176
00177 for (unsigned int i = 1; i <= pts.size(); ++i)
00178 {
00179 if (i == pts.size())
00180 {
00181 if (loop) d2 = make_unit_length(pts[0] - pts[i-1]);
00182 else d2 = d1;
00183 }
00184 else
00185 {
00186 d2 = make_unit_length(pts[i] - pts[i-1]);
00187 }
00188
00189 if (i == 1)
00190 {
00191 if (loop) d1 = make_unit_length(pts[0] - pts.back());
00192 else d1 = d2;
00193 }
00194
00195 const vec2d use_n = joinedNormal(d1, d2);
00196
00197 const vec2d pt1 = pts[i-1] - use_n*width;
00198 const vec2d pt2 = pts[i-1] + use_n*width;
00199
00200 canvas->vertex2(pt1);
00201 canvas->vertex2(pt2);
00202
00203 if (i == 1)
00204 {
00205 start_pt1 = pt1;
00206 start_pt2 = pt2;
00207 }
00208
00209 d1 = d2;
00210 }
00211
00212 if (loop)
00213 {
00214 canvas->vertex2(start_pt1);
00215 canvas->vertex2(start_pt2);
00216 }
00217
00218 canvas->end();
00219 }
00220
00221 static const char __attribute__((used)) vcid_groovx_gfx_linestrip_cc_utc20050626084024[] = "$Id: linestrip.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00222 #endif // !GROOVX_GFX_LINESTRIP_CC_UTC20050626084024_DEFINED