From 6540d31ff86f84e7fec205c93118ee7b71afa611 Mon Sep 17 00:00:00 2001 From: William Joye Date: Mon, 13 Mar 2017 17:19:54 -0400 Subject: simplify code --- tksao/frame/baseellipse.C | 260 +++++++++++++++++++++++++++------------------- tksao/frame/baseellipse.h | 10 +- tksao/frame/basefill.C | 10 ++ tksao/frame/basefill.h | 1 + tksao/frame/circle.C | 17 +++ tksao/frame/circle.h | 1 + tksao/frame/ellipse.C | 17 +++ tksao/frame/ellipse.h | 1 + 8 files changed, 211 insertions(+), 106 deletions(-) diff --git a/tksao/frame/baseellipse.C b/tksao/frame/baseellipse.C index 6b84669..cb0c63f 100644 --- a/tksao/frame/baseellipse.C +++ b/tksao/frame/baseellipse.C @@ -2,14 +2,17 @@ // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" -#include - #include "baseellipse.h" #include "fitsimage.h" +#define XPOINT_BLOCK 1024 + BaseEllipse::BaseEllipse(Base* p, const Vector& ctr, double ang) : BaseMarker(p, ctr, ang) { + xpoint_ =NULL; + xpointSize_ =0; + xpointNum_ =0; } BaseEllipse::BaseEllipse(Base* p, const Vector& ctr, @@ -20,14 +23,26 @@ BaseEllipse::BaseEllipse(Base* p, const Vector& ctr, const List& tag, const List& cb) : BaseMarker(p, ctr, ang, clr, dsh, w, f, t, prop, c, tag, cb) { + xpoint_ =NULL; + xpointSize_ =0; + xpointNum_ =0; } -BaseEllipse::BaseEllipse(const BaseEllipse& a) : BaseMarker(a) {} +BaseEllipse::BaseEllipse(const BaseEllipse& a) : BaseMarker(a) +{ + xpoint_ =NULL; + xpointSize_ =0; + xpointNum_ =0; +} BaseEllipse::~BaseEllipse() { + if (xpoint_) + free(xpoint_); } +// renderX + void BaseEllipse::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) { @@ -99,6 +114,10 @@ void BaseEllipse::renderXEllipse(Drawable drawable, Coord::InternalSystem sys, for (int i=0; i= xpointSize_) { + xpointSize_ += XPOINT_BLOCK*sizeof(XPoint); + xpoint_ = (XPoint*)realloc(xpoint_, xpointSize_); + } + XPoint* ptr = xpoint_+xpointNum_; + (*ptr).x = (*xpoint_).x; + (*ptr).y = (*xpoint_).y; + + // if dashed, fake it + GC lgc; + if ((properties & SOURCE) && !(properties & DASH)) + lgc = renderXGC(mode); + else { + // set width, color, dash + switch (mode) { + case SRC: + XSetForeground(display, gc, color); + renderXLineNoDash(gc); + lgc = gc; + break; + case XOR: + renderXLineNoDash(gcxor); + lgc = gcxor; + break; + } + } + + renderXEllipseDraw(drawable, lgc, xpoint_, xpointNum_); + + if (xpoint_) + free(xpoint_); + xpoint_ =NULL; + xpointSize_ =0; + xpointNum_ =0; + } +} + +void BaseEllipse::renderXEllipseDraw(Drawable drawable, GC lgc, + XPoint* pts, int cnt) +{ + if ((properties & SOURCE) && !(properties & DASH)) + XDrawLines(display, drawable, lgc, pts, cnt, CoordModeOrigin); + else { + // crude attempt to clip unwanted drawlines + // only works for SRC + for (int ii=0; iidd[1] ? dd[0] : dd[1]; + + // calculate incr + // this is a crude attempt to limit the number of iterations + // we want a min for very small segments, but not that large for + // high zoom or elongated curves + float aa = int(log(max))*5; + float incr = 1./(aa > 2 ? aa : 2); + + float tt = incr; + while (tt<=1+FLT_EPSILON) { + float xx = pow(tt,3)*(t2x+3*(x1x-x2x)-t1x) + +3*pow(tt,2)*(t1x-2*x1x+x2x) + +3*tt*(x1x-t1x)+t1x; + float yy = pow(tt,3)*(t2y+3*(x1y-x2y)-t1y) + +3*pow(tt,2)*(t1y-2*x1y+x2y) + +3*tt*(x1y-t1y)+t1y; + + xpointNum_++; + if (xpointNum_*sizeof(XPoint) >= xpointSize_) { + xpointSize_ += XPOINT_BLOCK*sizeof(XPoint); + xpoint_ = (XPoint*)realloc(xpoint_, xpointSize_); + } + XPoint* ptr = xpoint_+xpointNum_; + (*ptr).x = xx; + (*ptr).y = yy; + + tt += incr; + } +} + +// this routine maps the desired angle to an angle to be used with XDrawArc +double BaseEllipse::xyz(Vector rr, double aa) +{ + // just in case + if (!rr[0] || !rr[1]) + return aa; + + int flip=0; + while (aa>M_PI) { + aa -= M_PI; + flip++; + } + + double tt = rr[1]*rr[1]*cos(aa)*cos(aa)+rr[0]*rr[0]*sin(aa)*sin(aa); + double ss =0; + if (tt>0) + ss = 1./sqrt(tt); + + double bb = rr[1]*ss*cos(aa); + return acos(bb)+M_PI*flip; +} + void BaseEllipse::renderXInclude(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) @@ -180,12 +326,8 @@ void BaseEllipse::renderXInclude(Drawable drawable, // Matrix mm = fwdMatrix(); double theta = degToRad(45); - Vector r1 = fwdMap(Vector(annuli_[numAnnuli_-1][0]*cos(theta), - annuli_[numAnnuli_-1][1]*sin(theta)), - sys); - Vector r2 = fwdMap(Vector(-annuli_[numAnnuli_-1][0]*cos(theta), - -annuli_[numAnnuli_-1][1]*sin(theta)), - sys); + Vector r1 = fwdMap(Vector(annuli_[numAnnuli_-1][0]*cos(theta), annuli_[numAnnuli_-1][1]*sin(theta)), sys); + Vector r2 = fwdMap(Vector(-annuli_[numAnnuli_-1][0]*cos(theta), -annuli_[numAnnuli_-1][1]*sin(theta)), sys); GC lgc = renderXGC(mode); if (mode == SRC) @@ -195,6 +337,8 @@ void BaseEllipse::renderXInclude(Drawable drawable, } } +// renderPS + void BaseEllipse::renderPS(int mode) { Vector r = annuli_[numAnnuli_-1]; Vector z = parent->zoom(); @@ -207,7 +351,7 @@ void BaseEllipse::renderPS(int mode) { if (isRound && isScale && isOrient && parent->isAzElZero()) renderPSCircle(mode); else - renderPSEllipseCurve(mode); + renderPSEllipse(mode); } void BaseEllipse::renderPSCircle(int mode) @@ -251,7 +395,7 @@ void BaseEllipse::renderPSCircleDraw(Vector& cc, double l, float a1, float a2) Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); } -void BaseEllipse::renderPSEllipseCurve(int mode) +void BaseEllipse::renderPSEllipse(int mode) { renderPSGC(mode); @@ -691,97 +835,3 @@ Vector BaseEllipse::intersect(Vector rr, double aa) return Vector(ss*cos(aa),ss*sin(aa)); } -void BaseEllipse::XDrawCurve(Drawable drawable, RenderMode mode, - Vector& t1, Vector& x1, - Vector& x2, Vector& t2) -{ - // if dashed, fake it - GC lgc; - if ((properties & SOURCE) && !(properties & DASH)) - lgc = renderXGC(mode); - else { - // set width, color, dash - switch (mode) { - case SRC: - XSetForeground(display, gc, color); - renderXLineNoDash(gc); - lgc = gc; - break; - case XOR: - renderXLineNoDash(gcxor); - lgc = gcxor; - break; - } - } - - float t1x = t1[0]; - float t1y = t1[1]; - float t2x = t2[0]; - float t2y = t2[1]; - - float x1x = x1[0]; - float x1y = x1[1]; - float x2x = x2[0]; - float x2y = x2[1]; - - float rx = t1x; - float ry = t1y; - - Vector dd = (t2-t1).abs(); - float max = dd[0]>dd[1] ? dd[0] : dd[1]; - - // calculate incr - // this is a crude attempt to limit the number of iterations - // we want a min for very small segments, but not that large for - // high zoom or elongated curves - float aa = int(log(max))*5; - float incr = 1./(aa > 2 ? aa : 2); - - int dash=0; - float tt = incr; - while (tt<=1+FLT_EPSILON) { - float xx = pow(tt,3)*(t2x+3*(x1x-x2x)-t1x) - +3*pow(tt,2)*(t1x-2*x1x+x2x) - +3*tt*(x1x-t1x)+t1x; - float yy = pow(tt,3)*(t2y+3*(x1y-x2y)-t1y) - +3*pow(tt,2)*(t1y-2*x1y+x2y) - +3*tt*(x1y-t1y)+t1y; - - // crude attempt to clip unwanted drawlines - // only works for SRC - if ((properties & SOURCE) && !(properties & DASH)) - XDrawLine(display, drawable, lgc, rx, ry, xx, yy); - else { - if (dash) - XDrawLine(display, drawable, lgc, rx, ry, xx, yy); - dash = !dash; - } - - rx = xx; - ry = yy; - - tt += incr; - } -} - -// this routine maps the desired angle to an angle to be used with XDrawArc -double BaseEllipse::xyz(Vector rr, double aa) -{ - // just in case - if (!rr[0] || !rr[1]) - return aa; - - int flip=0; - while (aa>M_PI) { - aa -= M_PI; - flip++; - } - - double tt = rr[1]*rr[1]*cos(aa)*cos(aa)+rr[0]*rr[0]*sin(aa)*sin(aa); - double ss =0; - if (tt>0) - ss = 1./sqrt(tt); - - double bb = rr[1]*ss*cos(aa); - return acos(bb)+M_PI*flip; -} diff --git a/tksao/frame/baseellipse.h b/tksao/frame/baseellipse.h index 834b584..117ad8a 100644 --- a/tksao/frame/baseellipse.h +++ b/tksao/frame/baseellipse.h @@ -5,9 +5,16 @@ #ifndef __baseellipse_h__ #define __baseellipse_h__ +#include + #include "basemarker.h" class BaseEllipse : public BaseMarker { + protected: + XPoint* xpoint_; + int xpointSize_; + int xpointNum_; + private: double xyz(Vector rr, double ang); void XDrawCurve(Drawable, RenderMode, Vector&, Vector&, Vector&, Vector&); @@ -21,7 +28,7 @@ class BaseEllipse : public BaseMarker { void renderXInclude(Drawable, Coord::InternalSystem, RenderMode); void renderPSCircle(int); - void renderPSEllipseCurve(int); + void renderPSEllipse(int); void renderPSEllipsePrep(double, double, double, double, Vector&); void renderPSEllipseArc(double, double, Vector&); void renderPSInclude(int); @@ -45,6 +52,7 @@ class BaseEllipse : public BaseMarker { protected: void renderX(Drawable, Coord::InternalSystem, RenderMode); virtual void renderXCircleDraw(Drawable, GC, Vector&, Vector&, int, int); + virtual void renderXEllipseDraw(Drawable, GC, XPoint*, int); void renderPS(int); virtual void renderPSCircleDraw(Vector& cc, double l, float a1, float a2); virtual void renderPSEllipseArcDraw(Vector&, Vector&, Vector&, Vector&); diff --git a/tksao/frame/basefill.C b/tksao/frame/basefill.C index 4da1ae5..91e5171 100644 --- a/tksao/frame/basefill.C +++ b/tksao/frame/basefill.C @@ -42,6 +42,16 @@ void BaseFillEllipse::renderXCircleDraw(Display* display, Drawable drawable, XDrawArc(display, drawable, lgc, st[0], st[1], size[0], size[1], a1, aa); } +void BaseFillEllipse::renderXEllipseDraw(Display* display, Drawable drawable, + GC lgc, + XPoint* pts, int cnt) +{ + if (fill_) + XFillPolygon(display, drawable, lgc, pts, cnt, Convex, CoordModeOrigin); + else + XDrawLines(display, drawable, lgc, pts, cnt, CoordModeOrigin); +} + void BaseFillEllipse::renderPSCircleDraw(Base* parent, Vector& cc, double l, float a1, float a2) diff --git a/tksao/frame/basefill.h b/tksao/frame/basefill.h index f50adcf..5e2dd2c 100644 --- a/tksao/frame/basefill.h +++ b/tksao/frame/basefill.h @@ -27,6 +27,7 @@ class BaseFill { class BaseFillEllipse : public BaseFill { protected: void renderXCircleDraw(Display*, Drawable, GC, Vector&, Vector&, int, int); + void renderXEllipseDraw(Display*, Drawable, GC, XPoint*, int); void renderPSCircleDraw(Base*, Vector&, double, float, float); void renderPSEllipseArcDraw(Base*, Vector&, Vector&, Vector&, Vector&, Vector&); diff --git a/tksao/frame/circle.C b/tksao/frame/circle.C index 3015d07..87d29cb 100644 --- a/tksao/frame/circle.C +++ b/tksao/frame/circle.C @@ -61,6 +61,23 @@ void Circle::renderXCircleDraw(Drawable drawable, GC lgc, BaseFillEllipse::renderXCircleDraw(display, drawable, lgc, st, size, a1, aa); } +void Circle::renderXEllipseDraw(Drawable drawable, GC lgc, + XPoint* pts, int cnt) +{ + if (fill_ || ((properties & SOURCE) && !(properties & DASH))) + BaseFillEllipse::renderXEllipseDraw(display, drawable, lgc, pts, cnt); + else { + // crude attempt to clip unwanted drawlines + // only works for SRC + for (int ii=0; ii