summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2017-03-13 21:19:54 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2017-03-13 21:19:54 (GMT)
commit6540d31ff86f84e7fec205c93118ee7b71afa611 (patch)
treedb3a6e0b7293696beda267f157d1939989679184
parent8536c60bd238b8a901a590d1dc38c5727ca39305 (diff)
downloadblt-6540d31ff86f84e7fec205c93118ee7b71afa611.zip
blt-6540d31ff86f84e7fec205c93118ee7b71afa611.tar.gz
blt-6540d31ff86f84e7fec205c93118ee7b71afa611.tar.bz2
simplify code
-rw-r--r--tksao/frame/baseellipse.C260
-rw-r--r--tksao/frame/baseellipse.h10
-rw-r--r--tksao/frame/basefill.C10
-rw-r--r--tksao/frame/basefill.h1
-rw-r--r--tksao/frame/circle.C17
-rw-r--r--tksao/frame/circle.h1
-rw-r--r--tksao/frame/ellipse.C17
-rw-r--r--tksao/frame/ellipse.h1
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 <tk.h>
-
#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>& tag, const List<CallBack>& 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<numAnnuli_; i++) {
Vector r = annuli_[i];
+ xpointSize_ = XPOINT_BLOCK*sizeof(XPoint);
+ xpoint_ = (XPoint*)malloc(xpointSize_);
+ xpointNum_ =0;
+
int s1 =0;
int s2 =0;
for (int i=0; i<8; i++) {
@@ -115,6 +134,60 @@ void BaseEllipse::renderXEllipse(Drawable drawable, Coord::InternalSystem sys,
if (s1&&s2)
s1=s2=0;
}
+
+ // close the loop
+ xpointNum_++;
+ if (xpointNum_*sizeof(XPoint) >= 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; ii<xpointNum_; ii+=2) {
+ XPoint* ptr1 = xpoint_+ii;
+ XPoint* ptr2 = xpoint_+ii+1;
+ XDrawLine(display, drawable, lgc,
+ (*ptr1).x, (*ptr1).y, (*ptr2).x, (*ptr2).y);
+ }
}
}
@@ -169,9 +242,82 @@ void BaseEllipse::renderXEllipseArc(Drawable drawable,
Vector xx2 = fwdMap(x2*FlipY(),sys);
Vector tt1 = fwdMap(t1*FlipY(),sys);
+ if (xpointNum_ == 0) {
+ (*xpoint_).x = tt0[0];
+ (*xpoint_).y = tt0[1];
+ }
+
XDrawCurve(drawable, mode, tt0, xx1, xx2, tt1);
}
+void BaseEllipse::XDrawCurve(Drawable drawable, RenderMode mode,
+ Vector& t1, Vector& x1,
+ Vector& x2, Vector& t2)
+{
+ 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];
+
+ 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);
+
+ 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 <tk.h>
+
#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<xpointNum_; ii+=2) {
+ XPoint* ptr1 = xpoint_+ii;
+ XPoint* ptr2 = xpoint_+ii+1;
+ XDrawLine(display, drawable, lgc,
+ (*ptr1).x, (*ptr1).y, (*ptr2).x, (*ptr2).y);
+ }
+ }
+}
+
void Circle::renderPSCircleDraw(Vector& cc, double l, float a1, float a2)
{
BaseFillEllipse::renderPSCircleDraw(parent, cc, l, a1, a2);
diff --git a/tksao/frame/circle.h b/tksao/frame/circle.h
index 1d7ff77..ed26b7b 100644
--- a/tksao/frame/circle.h
+++ b/tksao/frame/circle.h
@@ -11,6 +11,7 @@
class Circle : public BaseEllipse, public BaseFillEllipse {
protected:
void renderXCircleDraw(Drawable, GC, Vector&, Vector&, int, int);
+ void renderXEllipseDraw(Drawable, GC, XPoint*, int);
void renderPSCircleDraw(Vector& cc, double l, float a1, float a2);
void renderPSEllipseArcDraw(Vector&, Vector&, Vector&, Vector&);
diff --git a/tksao/frame/ellipse.C b/tksao/frame/ellipse.C
index 7992090..0a53023 100644
--- a/tksao/frame/ellipse.C
+++ b/tksao/frame/ellipse.C
@@ -49,6 +49,23 @@ void Ellipse::renderXCircleDraw(Drawable drawable, GC lgc,
BaseFillEllipse::renderXCircleDraw(display, drawable, lgc, st, size, a1, aa);
}
+void Ellipse::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<xpointNum_; ii+=2) {
+ XPoint* ptr1 = xpoint_+ii;
+ XPoint* ptr2 = xpoint_+ii+1;
+ XDrawLine(display, drawable, lgc,
+ (*ptr1).x, (*ptr1).y, (*ptr2).x, (*ptr2).y);
+ }
+ }
+}
+
void Ellipse::renderPSCircleDraw(Vector& cc, double l, float a1, float a2)
{
BaseFillEllipse::renderPSCircleDraw(parent, cc, l, a1, a2);
diff --git a/tksao/frame/ellipse.h b/tksao/frame/ellipse.h
index 25bf115..5b95a7a 100644
--- a/tksao/frame/ellipse.h
+++ b/tksao/frame/ellipse.h
@@ -11,6 +11,7 @@
class Ellipse : public BaseEllipse, public BaseFillEllipse {
protected:
void renderXCircleDraw(Drawable, GC, Vector&, Vector&, int, int);
+ void renderXEllipseDraw(Drawable, GC, XPoint*, int);
void renderPSCircleDraw(Vector& cc, double l, float a1, float a2);
void renderPSEllipseArcDraw(Vector&, Vector&, Vector&, Vector&);