summaryrefslogtreecommitdiffstats
path: root/tksao/frame/projection.C
diff options
context:
space:
mode:
Diffstat (limited to 'tksao/frame/projection.C')
-rw-r--r--tksao/frame/projection.C434
1 files changed, 434 insertions, 0 deletions
diff --git a/tksao/frame/projection.C b/tksao/frame/projection.C
new file mode 100644
index 0000000..186266f
--- /dev/null
+++ b/tksao/frame/projection.C
@@ -0,0 +1,434 @@
+// Copyright (C) 1999-2016
+// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
+// For conditions of distribution and use, see copyright notice in "copyright"
+
+#include <tk.h>
+
+#include "projection.h"
+#include "fitsimage.h"
+
+Projection::Projection(const Projection& a) : BaseLine(a)
+{
+ width = a.width;
+ p3 = a.p3;
+ p4 = a.p4;
+}
+
+Projection::Projection(Base* p, const Vector& ptr1, const Vector& ptr2,
+ double wd,
+ const char* clr, int* dsh,
+ int wth, const char* fnt, const char* txt,
+ unsigned short prop, const char* cmt,
+ const List<Tag>& tg, const List<CallBack>& cb)
+ : BaseLine(p, ptr1, ptr2, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb)
+{
+ width = wd;
+
+ strcpy(type_,"projection");
+ handle = new Vector[3];
+ numHandle = 3;
+
+ // this causes a focus problem with MacOSX and X11?
+ // analysis(PLOT2D,1);
+ updateBBox();
+}
+
+void Projection::renderX(Drawable drawable, Coord::InternalSystem sys,
+ RenderMode mode)
+{
+ GC lgc = renderXGC(mode);
+
+ Vector aa = parent->mapFromRef(p1,sys);
+ Vector bb = parent->mapFromRef(p2,sys);
+
+ XDrawLine(display, drawable, lgc, aa[0], aa[1], bb[0], bb[1]);
+
+ if (width>0) {
+ renderXLineDash(lgc);
+
+ Matrix imm = bckMatrix();
+ Vector a = p1*imm;
+ Vector b = p2*imm;
+ Vector c = Vector(0,-width);
+
+ Vector ll = fwdMap(a,sys);
+ Vector lr = fwdMap(b,sys);
+ Vector ul = fwdMap(a+c,sys);
+ Vector ur = fwdMap(b+c,sys);
+
+ XDrawLine(display, drawable, lgc, lr[0], lr[1], ur[0], ur[1]);
+ XDrawLine(display, drawable, lgc, ur[0], ur[1], ul[0], ul[1]);
+ XDrawLine(display, drawable, lgc, ul[0], ul[1], ll[0], ll[1]);
+ }
+}
+
+GC Projection::renderXGC(RenderMode mode)
+{
+ // set width, color, dash
+ switch (mode) {
+ case SRC:
+ XSetForeground(display, gc, color);
+ renderXLineNoDash(gc);
+ return gc;
+
+ case XOR:
+ renderXLineDash(gcxor);
+ return gcxor;
+ }
+}
+
+void Projection::renderPS(int mode)
+{
+ renderPSGC(mode);
+
+ Vector aa = parent->mapFromRef(p1,Coord::CANVAS);
+ Vector bb = parent->mapFromRef(p2,Coord::CANVAS);
+ {
+ ostringstream str;
+ str << "newpath "
+ << aa.TkCanvasPs(parent->canvas) << ' '
+ << "moveto "
+ << bb.TkCanvasPs(parent->canvas) << ' '
+ << "lineto stroke" << endl << ends;
+ Tcl_AppendResult(parent->interp, str.str().c_str(), NULL);
+ }
+
+ if (width>0) {
+ renderPSLineDash();
+
+ Matrix imm = bckMatrix();
+ Vector a = p1*imm;
+ Vector b = p2*imm;
+ Vector c = Vector(0,-width);
+
+ Vector ll = fwdMap(a,Coord::CANVAS);
+ Vector lr = fwdMap(b,Coord::CANVAS);
+ Vector ul = fwdMap(a+c,Coord::CANVAS);
+ Vector ur = fwdMap(b+c,Coord::CANVAS);
+
+ ostringstream str;
+ str << "newpath "
+ << lr.TkCanvasPs(parent->canvas) << ' '
+ << "moveto "
+ << ur.TkCanvasPs(parent->canvas) << ' '
+ << "lineto "
+ << ul.TkCanvasPs(parent->canvas) << ' '
+ << "lineto "
+ << ll.TkCanvasPs(parent->canvas) << ' '
+ << "lineto stroke" << endl << ends;
+ Tcl_AppendResult(parent->interp, str.str().c_str(), NULL);
+ }
+}
+
+void Projection::renderPSGC(int mode)
+{
+ renderPSColor(mode, parent->getXColor(colorName));
+ renderPSLineNoDash();
+}
+
+#ifdef MAC_OSX_TK
+void Projection::renderMACOSX()
+{
+ renderMACOSXGC();
+
+ Vector aa = parent->mapFromRef(p1,Coord::CANVAS);
+ Vector bb = parent->mapFromRef(p2,Coord::CANVAS);
+
+ macosxDrawLine(aa,bb);
+
+ if (width>0) {
+ renderMACOSXLineDash();
+
+ Matrix imm = bckMatrix();
+ Vector a = p1*imm;
+ Vector b = p2*imm;
+ Vector c = Vector(0,-width);
+
+ Vector ll = fwdMap(a,Coord::CANVAS);
+ Vector lr = fwdMap(b,Coord::CANVAS);
+ Vector ul = fwdMap(a+c,Coord::CANVAS);
+ Vector ur = fwdMap(b+c,Coord::CANVAS);
+
+ macosxDrawLine(lr,ur);
+ macosxDrawLine(ur,ul);
+ macosxDrawLine(ul,ll);
+ }
+}
+
+void Projection::renderMACOSXGC()
+{
+ macosxColor(parent->getXColor(colorName));
+ renderMACOSXLineNoDash();
+}
+#endif
+
+#ifdef __WIN32
+void Projection::renderWIN32()
+{
+ renderWIN32GC();
+
+ Vector aa = parent->mapFromRef(p1,Coord::CANVAS);
+ Vector bb = parent->mapFromRef(p2,Coord::CANVAS);
+
+ win32DrawLine(aa,bb);
+
+ if (width>0) {
+ renderWIN32LineDash();
+
+ Matrix imm = bckMatrix();
+ Vector a = p1*imm;
+ Vector b = p2*imm;
+ Vector c = Vector(0,-width);
+
+ Vector ll = fwdMap(a,Coord::CANVAS);
+ Vector lr = fwdMap(b,Coord::CANVAS);
+ Vector ul = fwdMap(a+c,Coord::CANVAS);
+ Vector ur = fwdMap(b+c,Coord::CANVAS);
+
+ win32DrawLine(lr,ur);
+ win32DrawLine(ur,ul);
+ win32DrawLine(ul,ll);
+ }
+}
+
+void Projection::renderWIN32GC()
+{
+ win32Color(parent->getXColor(colorName));
+ renderWIN32LineNoDash();
+}
+#endif
+
+// Support
+
+void Projection::updateHandles()
+{
+ center = (p2-p1)/2 + p1;
+ angle = (p2-p1).angle();
+
+ Matrix imm = bckMatrix();
+ Vector a = p1*imm;
+ Vector b = p2*imm;
+ Vector c = Vector(0,-width);
+ p3 = fwdMap(a+c,Coord::CANVAS);
+ p4 = fwdMap(b+c,Coord::CANVAS);
+ Vector hh = fwdMap(((b-a)/2+a)+c,Coord::CANVAS);
+
+ // generate handles in Coord::CANVAS coords
+ handle[0] = parent->mapFromRef(p1,Coord::CANVAS);
+ handle[1] = parent->mapFromRef(p2,Coord::CANVAS);
+ handle[2] = hh;
+}
+
+void Projection::calcAllBBox()
+{
+ // p3/p4 are already in Coord::CANVAS coords
+ bbox.bound(p3);
+ bbox.bound(p4);
+ Marker::calcAllBBox();
+}
+
+void Projection::edit(const Vector& v, int h)
+{
+ switch (h) {
+ case 1:
+ p1 = v;
+ break;
+ case 2:
+ p2 = v;
+ break;
+ case 3:
+ Matrix mm = bckMatrix();
+ width = -(v * mm)[1];
+ if (width<0)
+ width = 0;
+ break;
+ }
+
+ updateBBox();
+ doCallBack(CallBack::EDITCB);
+}
+
+int Projection::isIn(const Vector& v)
+{
+ Vector zz = parent->zoom();
+ if (width * zz.length() > parent->markerEpsilon) {
+ Matrix imm = bckMatrix();
+ Vector a = p1*imm;
+ Vector b = p2*imm;
+
+ Vector vv = -bckMap(v,Coord::CANVAS);
+ return (vv[0]>a[0] && vv[0]<b[0] && vv[1]>0 && vv[1]<width);
+ }
+ else
+ return BaseLine::isIn(v);
+}
+
+void Projection::set(const Vector& v1, const Vector& v2, double wd)
+{
+ p1 = v1;
+ p2 = v2;
+ width = wd;
+
+ updateBBox();
+ doCallBack(CallBack::EDITCB);
+}
+
+void Projection::setWidth(double wd)
+{
+ width = wd;
+ if (width<0)
+ width = 0;
+
+ updateBBox();
+ doCallBack(CallBack::EDITCB);
+}
+
+void Projection::updateCoords(const Matrix& mx)
+{
+ width = (Vector(0,width) * Scale(mx))[1];
+ BaseLine::updateCoords(mx);
+}
+
+void Projection::analysis(AnalysisTask mm, int which)
+{
+ switch (mm) {
+ case PLOT2D:
+ if (!analysisPlot2d_ && which) {
+ addCallBack(CallBack::MOVECB, analysisPlot2dCB_[0],
+ parent->options->cmdName);
+ addCallBack(CallBack::EDITCB, analysisPlot2dCB_[0],
+ parent->options->cmdName);
+ addCallBack(CallBack::UPDATECB, analysisPlot2dCB_[0],
+ parent->options->cmdName);
+ addCallBack(CallBack::DELETECB, analysisPlot2dCB_[1],
+ parent->options->cmdName);
+ }
+ if (analysisPlot2d_ && !which) {
+ deleteCallBack(CallBack::MOVECB, analysisPlot2dCB_[0]);
+ deleteCallBack(CallBack::EDITCB, analysisPlot2dCB_[0]);
+ deleteCallBack(CallBack::UPDATECB, analysisPlot2dCB_[0]);
+ deleteCallBack(CallBack::DELETECB, analysisPlot2dCB_[1]);
+ }
+
+ analysisPlot2d_ = which;
+ break;
+ default:
+ // na
+ break;
+ }
+}
+
+void Projection::analysisPlot2d(char* xname, char* yname,
+ char* xcname, char* ycname,
+ Coord::CoordSystem sys, Coord::SkyFrame sky,
+ Marker::AnalysisMethod method)
+{
+ double* x;
+ double* y;
+ double* xc;
+ double* yc;
+
+ int num = parent->markerAnalysisPlot2d(this, &x, &y, &xc, &yc, p1, p2, width,
+ sys, sky, method);
+ analysisXYEEResult(xname, yname, xcname, ycname, x, y, xc, yc, num);
+}
+
+// list
+
+void Projection::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky,
+ Coord::SkyFormat format, int conj, int strip)
+{
+ if (!strip) {
+ FitsImage* ptr = parent->findFits(sys,center);
+ listPre(str, sys, sky, ptr, strip, 1);
+
+ switch (sys) {
+ case Coord::IMAGE:
+ case Coord::PHYSICAL:
+ case Coord::DETECTOR:
+ case Coord::AMPLIFIER:
+ listNonCel(ptr, str, sys);
+ break;
+ default:
+ if (ptr->hasWCSEqu(sys)) {
+ double ww = ptr->mapLenFromRef(width,sys,Coord::ARCSEC);
+ switch (format) {
+ case Coord::DEGREES:
+ {
+ Vector v1 = ptr->mapFromRef(p1,sys,sky);
+ Vector v2 = ptr->mapFromRef(p2,sys,sky);
+ str << type_ << '(' << setprecision(10) << v1 << ',' << v2 << ','
+ << setprecision(3) << fixed << ww << '"' << ')';
+ str.unsetf(ios_base::floatfield);
+ }
+ break;
+ case Coord::SEXAGESIMAL:
+ str << type_ << '(';
+ listRADEC(ptr,p1,sys,sky,format);
+ str << ra << ',' << dec << ',';
+ listRADEC(ptr,p2,sys,sky,format);
+ str << ra << ',' << dec << ',';
+
+ str << setprecision(3) << fixed << ww << '"' << ')';
+ str.unsetf(ios_base::floatfield);
+ break;
+ }
+ }
+ else
+ listNonCel(ptr, str, sys);
+ }
+
+ if (conj)
+ str << " ||";
+
+ listProperties(str, 0);
+ }
+}
+
+void Projection::listNonCel(FitsImage* ptr, ostream& str,
+ Coord::CoordSystem sys)
+{
+ Vector v1 = ptr->mapFromRef(p1,sys);
+ Vector v2 = ptr->mapFromRef(p2,sys);
+ double ww = ptr->mapLenFromRef(width,sys);
+ str << type_ << '(' << setprecision(8) << v1 << ',' << v2 << ','
+ << ww << ')';
+}
+
+void Projection::listXML(ostream& str, Coord::CoordSystem sys,
+ Coord::SkyFrame sky, Coord::SkyFormat format)
+{
+ FitsImage* ptr = parent->findFits(sys,center);
+ Vector vv[2];
+ vv[0] = p1;
+ vv[1] = p2;
+ double rr = ptr->mapLenFromRef(width,sys,Coord::ARCSEC);
+
+ XMLRowInit();
+ XMLRow(XMLSHAPE,type_);
+
+ XMLRowPoint(ptr,sys,sky,format,vv,2);
+
+ switch (sys) {
+ case Coord::IMAGE:
+ case Coord::PHYSICAL:
+ case Coord::DETECTOR:
+ case Coord::AMPLIFIER:
+ XMLRow(XMLR,rr,8);
+ break;
+ default:
+ if (ptr->hasWCS(sys)) {
+ if (ptr->hasWCSCel(sys))
+ XMLRowARCSEC(XMLR,rr);
+ else
+ XMLRow(XMLR,rr,8);
+ }
+ break;
+ }
+
+ XMLRowProps(ptr,sys);
+ XMLRowEnd(str);
+}
+
+
+