diff options
-rw-r--r-- | src/bltGrElemBar.C | 2 | ||||
-rw-r--r-- | src/bltGrElemLine.C | 60 | ||||
-rw-r--r-- | src/bltGrElemLine.h | 2 | ||||
-rw-r--r-- | src/bltGrMisc.h | 5 | ||||
-rw-r--r-- | src/bltGrPenBar.C | 2 | ||||
-rw-r--r-- | src/bltGrPenLine.C | 2 | ||||
-rw-r--r-- | src/bltVecCmd.C | 3 | ||||
-rw-r--r-- | src/bltVecInt.h | 5 | ||||
-rw-r--r-- | tests/linemarker.tcl | 2 | ||||
-rw-r--r-- | tests/polygonmarker.tcl | 2 |
10 files changed, 77 insertions, 8 deletions
diff --git a/src/bltGrElemBar.C b/src/bltGrElemBar.C index fa02302..efba3b5 100644 --- a/src/bltGrElemBar.C +++ b/src/bltGrElemBar.C @@ -84,7 +84,7 @@ static Tk_OptionSpec optionSpecs[] = { "1", -1, Tk_Offset(BarElementOptions, builtinPen.errorBarLineWidth), 0, NULL, 0}, {TK_OPTION_PIXELS, "-errorbarcap", "errorBarCap", "ErrorBarCap", - "2", -1, Tk_Offset(BarElementOptions, builtinPen.errorBarCapWidth), + "6", -1, Tk_Offset(BarElementOptions, builtinPen.errorBarCapWidth), 0, NULL, 0}, {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, -1, 0, 0, "-foreground", 0}, {TK_OPTION_SYNONYM, "-fill", NULL, NULL, NULL, -1, 0, 0, "-background", 0}, diff --git a/src/bltGrElemLine.C b/src/bltGrElemLine.C index 7241473..438a005 100644 --- a/src/bltGrElemLine.C +++ b/src/bltGrElemLine.C @@ -121,7 +121,7 @@ static Tk_OptionSpec optionSpecs[] = { "1", -1, Tk_Offset(LineElementOptions, builtinPen.errorBarLineWidth), 0, NULL, 0}, {TK_OPTION_PIXELS, "-errorbarcap", "errorBarCap", "ErrorBarCap", - "2", -1, Tk_Offset(LineElementOptions, builtinPen.errorBarCapWidth), + "6", -1, Tk_Offset(LineElementOptions, builtinPen.errorBarCapWidth), 0, NULL, 0}, {TK_OPTION_COLOR, "-fill", "fill", "Fill", NULL, -1, Tk_Offset(LineElementOptions, builtinPen.symbol.fillColor), @@ -1093,8 +1093,8 @@ void LineElement::ReducePoints(MapInfo *mapPtr, double tolerance) int* simple = (int*)malloc(mapPtr->nScreenPts * sizeof(int)); int* map = (int*)malloc(mapPtr->nScreenPts * sizeof(int)); Point2d *screenPts = (Point2d*)malloc(mapPtr->nScreenPts * sizeof(Point2d)); - int np = Blt_SimplifyLine(mapPtr->screenPts, 0, mapPtr->nScreenPts - 1, - tolerance, simple); + int np = simplify(mapPtr->screenPts, 0, mapPtr->nScreenPts - 1, + tolerance, simple); for (int ii=0; ii<np; ii++) { int kk = simple[ii]; screenPts[ii] = mapPtr->screenPts[kk]; @@ -1108,6 +1108,60 @@ void LineElement::ReducePoints(MapInfo *mapPtr, double tolerance) mapPtr->nScreenPts = np; } +/* Douglas-Peucker line simplification algorithm */ +int LineElement::simplify(Point2d *inputPts, int low, int high, + double tolerance, int *indices) +{ +#define StackPush(a) s++, stack[s] = (a) +#define StackPop(a) (a) = stack[s], s-- +#define StackEmpty() (s < 0) +#define StackTop() stack[s] + int split = -1; + double dist2, tolerance2; + int s = -1; /* Points to top stack item. */ + + int* stack = (int*)malloc(sizeof(int) * (high - low + 1)); + StackPush(high); + int count = 0; + indices[count++] = 0; + tolerance2 = tolerance * tolerance; + while (!StackEmpty()) { + dist2 = findSplit(inputPts, low, StackTop(), &split); + if (dist2 > tolerance2) + StackPush(split); + else { + indices[count++] = StackTop(); + StackPop(low); + } + } + free(stack); + return count; +} + +double LineElement::findSplit(Point2d *points, int i, int j, int *split) +{ + double maxDist2 = -1.0; + if ((i + 1) < j) { + int k; + double a = points[i].y - points[j].y; + double b = points[j].x - points[i].x; + double c = (points[i].x * points[j].y) - (points[i].y * points[j].x); + for (k = (i + 1); k < j; k++) { + double dist2 = (points[k].x * a) + (points[k].y * b) + c; + if (dist2 < 0.0) + dist2 = -dist2; + + if (dist2 > maxDist2) { + maxDist2 = dist2; /* Track the maximum. */ + *split = k; + } + } + /* Correction for segment length---should be redone if can == 0 */ + maxDist2 *= maxDist2 / (a * a + b * b); + } + return maxDist2; +} + void LineElement::GenerateSteps(MapInfo *mapPtr) { int newSize = ((mapPtr->nScreenPts - 1) * 2) + 1; diff --git a/src/bltGrElemLine.h b/src/bltGrElemLine.h index 2fa9c16..42dd6ef 100644 --- a/src/bltGrElemLine.h +++ b/src/bltGrElemLine.h @@ -152,6 +152,8 @@ class LineElement : public Element { double DistanceToY(int, int, Point2d*, Point2d*, Point2d*); void GetSymbolPostScriptInfo(Blt_Ps, LinePen*, int); void SymbolsToPostScript(Blt_Ps, LinePen*, int, int, Point2d*); + int simplify(Point2d*, int, int, double, int*); + double findSplit(Point2d*, int, int, int*); public: LineElement(Graph*, const char*, Tcl_HashEntry*); diff --git a/src/bltGrMisc.h b/src/bltGrMisc.h index b2feef6..e1e9aaa 100644 --- a/src/bltGrMisc.h +++ b/src/bltGrMisc.h @@ -41,6 +41,11 @@ #endif typedef struct { + double x; + double y; +} Point2d; + +typedef struct { double left; double right; double top; diff --git a/src/bltGrPenBar.C b/src/bltGrPenBar.C index 35b9890..3340a8c 100644 --- a/src/bltGrPenBar.C +++ b/src/bltGrPenBar.C @@ -43,7 +43,7 @@ static Tk_OptionSpec barPenOptionSpecs[] = { {TK_OPTION_PIXELS, "-errorbarwidth", "errorBarWidth","ErrorBarWidth", "1", -1, Tk_Offset(BarPenOptions, errorBarLineWidth), 0, NULL, 0}, {TK_OPTION_PIXELS, "-errorbarcap", "errorBarCap", "ErrorBarCap", - "2", -1, Tk_Offset(BarPenOptions, errorBarCapWidth), 0, NULL, 0}, + "6", -1, Tk_Offset(BarPenOptions, errorBarCapWidth), 0, NULL, 0}, {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, -1, 0, 0, "-foreground", 0}, {TK_OPTION_SYNONYM, "-fill", NULL, NULL, NULL, -1, 0, 0, "-background", 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", diff --git a/src/bltGrPenLine.C b/src/bltGrPenLine.C index cf4bcd2..455b5d7 100644 --- a/src/bltGrPenLine.C +++ b/src/bltGrPenLine.C @@ -177,7 +177,7 @@ static Tk_OptionSpec linePenOptionSpecs[] = { {TK_OPTION_PIXELS, "-errorbarwidth", "errorBarWidth", "ErrorBarWidth", "1", -1, Tk_Offset(LinePenOptions, errorBarLineWidth), 0, NULL, 0}, {TK_OPTION_PIXELS, "-errorbarcap", "errorBarCap", "ErrorBarCap", - "2", -1, Tk_Offset(LinePenOptions, errorBarCapWidth), 0, NULL, 0}, + "6", -1, Tk_Offset(LinePenOptions, errorBarCapWidth), 0, NULL, 0}, {TK_OPTION_COLOR, "-fill", "fill", "Fill", NULL, -1, Tk_Offset(LinePenOptions, symbol.fillColor), TK_OPTION_NULL_OK, NULL, 0}, diff --git a/src/bltVecCmd.C b/src/bltVecCmd.C index a448131..c697f41 100644 --- a/src/bltVecCmd.C +++ b/src/bltVecCmd.C @@ -55,6 +55,9 @@ #include "bltNsUtil.h" #include "bltSwitch.h" +extern int Blt_SimplifyLine (Point2d *origPts, int low, int high, + double tolerance, int *indices); + typedef int (VectorCmdProc)(Vector *vPtr, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]); diff --git a/src/bltVecInt.h b/src/bltVecInt.h index ad83fac..f63b129 100644 --- a/src/bltVecInt.h +++ b/src/bltVecInt.h @@ -52,6 +52,11 @@ #define FFT_SPECTRUM (1<<2) typedef struct { + double x; + double y; +} Point2d; + +typedef struct { Tcl_HashTable vectorTable; /* Table of vectors */ Tcl_HashTable mathProcTable; /* Table of vector math functions */ Tcl_HashTable indexProcTable; diff --git a/tests/linemarker.tcl b/tests/linemarker.tcl index 674aaf8..be6aa61 100644 --- a/tests/linemarker.tcl +++ b/tests/linemarker.tcl @@ -14,7 +14,7 @@ echo "Testing Line Marker..." #bltTest3 $graph marker $mm -bindtags {aa} bltTest3 $graph marker $mm -cap round bltTest3 $graph marker $mm -coords {1 50 1.5 100 2 150} -bltTest3 $graph marker $mm -dashes dashdot +bltTest3 $graph marker $mm -dashes "8 3" bltTest3 $graph marker $mm -dashoffset 10 bltTest3 $graph marker $mm -element data2 bltTest3 $graph marker $nn -fill yellow diff --git a/tests/polygonmarker.tcl b/tests/polygonmarker.tcl index 9b553d2..7dfa6f0 100644 --- a/tests/polygonmarker.tcl +++ b/tests/polygonmarker.tcl @@ -11,7 +11,7 @@ echo "Testing Polygon Marker..." #bltTest3 $graph marker $mm -bindtags {aa} bltTest3 $graph marker $mm -cap round bltTest3 $graph marker $mm -coords {1 50 1.5 100 2 150} -bltTest3 $graph marker $mm -dashes dashdot +bltTest3 $graph marker $mm -dashes "8 3" bltTest3 $graph marker $mm -element data2 bltTest3 $graph marker $mm -fill yellow bltTest3 $graph marker $mm -fillbg blue |