summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 530dbe4)
raw | patch | inline | side by side (parent: 530dbe4)
author | buliabyak <buliabyak@users.sourceforge.net> | |
Mon, 27 Aug 2007 00:36:33 +0000 (00:36 +0000) | ||
committer | buliabyak <buliabyak@users.sourceforge.net> | |
Mon, 27 Aug 2007 00:36:33 +0000 (00:36 +0000) |
src/livarot/Shape.h | patch | blob | history | |
src/livarot/ShapeMisc.cpp | patch | blob | history |
diff --git a/src/livarot/Shape.h b/src/livarot/Shape.h
index 9413cf9271ca07fdf783c98d3ec06223556a8dcc..6e25fd405bf7b099417459e3a1b26fc7ac27fe1b 100644 (file)
--- a/src/livarot/Shape.h
+++ b/src/livarot/Shape.h
// the result is NOT a polygon; you need a subsequent call to ConvertToShape to get a real polygon
int MakeOffset(Shape *of, double dec, JoinType join, double miter, bool do_profile=false, double cx = 0, double cy = 0, double radius = 0, NR::Matrix *i2doc = NULL);
+ int MakeRepel(Shape *of, double dec, JoinType join, double miter, bool do_profile=false, double cx = 0, double cy = 0, double radius = 0, NR::Matrix *i2doc = NULL);
+
int MakePush (Shape * a, JoinType join, double miter, bool do_profile, NR::Point c, NR::Point vector, double radius, NR::Matrix *i2doc = NULL);
int MakeJitter (Shape * a, JoinType join, double miter, bool do_profile, NR::Point c, double power, double radius, NR::Matrix *i2doc = NULL);
index 7590500af08fbdd8c0ae4a170641b80a1df16bef..199457a0b86aa91f35c1e488be9b2ccefee4b953 100644 (file)
@@ -812,7 +812,145 @@ Shape::MakePush (Shape * a, JoinType join, double miter, bool do_profile, NR::Po
return (done_something? 0 : shape_nothing_to_do);
}
-// pushing
+
+// attracting/repelling
+// modeled after MakeOffset black magic, the only difference being in the DoRight/LeftJoin parameters
+int
+Shape::MakeRepel (Shape * a, double dec, JoinType join, double miter, bool do_profile, double cx, double cy, double radius, NR::Matrix *i2doc)
+{
+ Reset (0, 0);
+ MakeBackData(a->_has_back_data);
+
+ bool done_something = false;
+
+ if (dec == 0)
+ {
+ _pts = a->_pts;
+ if (numberOfPoints() > maxPt)
+ {
+ maxPt = numberOfPoints();
+ if (_has_points_data) {
+ pData.resize(maxPt);
+ _point_data_initialised = false;
+ _bbox_up_to_date = false;
+ }
+ }
+
+ _aretes = a->_aretes;
+ if (numberOfEdges() > maxAr)
+ {
+ maxAr = numberOfEdges();
+ if (_has_edges_data)
+ eData.resize(maxAr);
+ if (_has_sweep_src_data)
+ swsData.resize(maxAr);
+ if (_has_sweep_dest_data)
+ swdData.resize(maxAr);
+ if (_has_raster_data)
+ swrData.resize(maxAr);
+ if (_has_back_data)
+ ebData.resize(maxAr);
+ }
+ return 0;
+ }
+ if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1 || a->type != shape_polygon)
+ return shape_input_err;
+
+ a->SortEdges ();
+
+ a->MakeSweepDestData (true);
+ a->MakeSweepSrcData (true);
+
+ for (int i = 0; i < a->numberOfEdges(); i++)
+ {
+ int stB = -1, enB = -1;
+ stB = a->CyclePrevAt (a->getEdge(i).st, i);
+ enB = a->CycleNextAt (a->getEdge(i).en, i);
+
+ NR::Point stD, seD, enD;
+ double stL, seL, enL;
+ stD = a->getEdge(stB).dx;
+ seD = a->getEdge(i).dx;
+ enD = a->getEdge(enB).dx;
+
+ stL = sqrt (dot(stD,stD));
+ seL = sqrt (dot(seD,seD));
+ enL = sqrt (dot(enD,enD));
+ MiscNormalize (stD);
+ MiscNormalize (enD);
+ MiscNormalize (seD);
+
+ NR::Point ptP;
+ int stNo, enNo;
+ ptP = a->getPoint(a->getEdge(i).st).x;
+
+ NR::Point this_vec;
+ if (do_profile && i2doc) {
+ double alpha = 1;
+ NR::Point c (cx, cy);
+ NR::Point to_center = ptP * (*i2doc) - c;
+ double x = (NR::L2(to_center)/radius);
+ if (x > 1) {
+ this_vec = NR::Point(0,0);
+ } else if (x <= 0) {
+ this_vec = NR::Point(0,0);
+ } else {
+ this_vec = (1/NR::L2(to_center)) * to_center; // normalize
+ this_vec = dec * (0.5 * cos (M_PI * (pow(x, alpha))) + 0.5) * this_vec;
+ }
+ } else {
+ this_vec = NR::Point(0,0);
+ }
+
+ if (NR::L2(this_vec) != 0)
+ done_something = true;
+
+ int usePathID=-1;
+ int usePieceID=0;
+ double useT=0.0;
+ if ( a->_has_back_data ) {
+ if ( a->ebData[i].pathID >= 0 && a->ebData[stB].pathID == a->ebData[i].pathID && a->ebData[stB].pieceID == a->ebData[i].pieceID
+ && a->ebData[stB].tEn == a->ebData[i].tSt ) {
+ usePathID=a->ebData[i].pathID;
+ usePieceID=a->ebData[i].pieceID;
+ useT=a->ebData[i].tSt;
+ } else {
+ usePathID=a->ebData[i].pathID;
+ usePieceID=0;
+ useT=0;
+ }
+ }
+ Path::DoLeftJoin (this, 0, join, ptP+this_vec, stD+this_vec, seD+this_vec, miter, stL, seL,
+ stNo, enNo,usePathID,usePieceID,useT);
+ a->swsData[i].stPt = enNo;
+ a->swsData[stB].enPt = stNo;
+ }
+
+
+ for (int i = 0; i < numberOfEdges(); i++)
+ Inverse (i);
+
+ if ( _has_back_data ) {
+ for (int i = 0; i < a->numberOfEdges(); i++)
+ {
+ int nEd=AddEdge (a->swsData[i].stPt, a->swsData[i].enPt);
+ ebData[nEd]=a->ebData[i];
+ }
+ } else {
+ for (int i = 0; i < a->numberOfEdges(); i++)
+ {
+ AddEdge (a->swsData[i].stPt, a->swsData[i].enPt);
+ }
+ }
+
+ a->MakeSweepSrcData (false);
+ a->MakeSweepDestData (false);
+
+ return (done_something? 0 : shape_nothing_to_do);
+}
+
+
+// roughening
// modeled after MakeOffset black magic, the only difference being in the DoRight/LeftJoin parameters
int
Shape::MakeJitter (Shape * a, JoinType join, double miter, bool do_profile, NR::Point c, double power, double radius, NR::Matrix *i2doc)