| |
| |
| #include "tgraphics.h" |
| |
| extern "C" { |
| #include "Tw/Gf.h" |
| #include "tvis.h" |
| } |
| |
| TGraphics::TGraphics(_TWIDGET *_gf, |
| int ras_x0, int ras_y0, |
| int ras_x1, int ras_y1, |
| int gf_x0, int gf_y0, |
| int gf_x1, int gf_y1, |
| int zoom_level) |
| : gf(_gf), currentPoint(0, 0), gfRegion(gf_x0, gf_y0, gf_x1, gf_y1), rasterRegion(ras_x0 - 1, ras_y0 - 1, ras_x1 + 1, ras_y1 + 1) |
| |
| , |
| zoomFactor(1), pixelSize(1) |
| { |
| double dx, dy; |
| int blx, bly; |
| |
| if (zoom_level > 0) |
| zoomFactor = 1 << zoom_level; |
| else if (zoom_level < 0) |
| zoomFactor = 1.0 / (1 << -zoom_level); |
| pixelSize = 1.0 / zoomFactor; |
| |
| blx = ras_x0 - gf_x0 / zoomFactor; |
| bly = ras_y0 - gf_y0 / zoomFactor; |
| dx = 0.5 - blx; |
| dy = 0.5 - bly; |
| |
| GfPushMatrix(gf); |
| GfTranslate(gf, -0.5, -0.5); |
| GfScale(gf, zoomFactor, zoomFactor); |
| GfTranslate(gf, dx, dy); |
| } |
| |
| |
| |
| TGraphics::~TGraphics() |
| { |
| GfPopMatrix(gf); |
| } |
| |
| |
| |
| void TGraphics::setColor(int r, int g, int b) |
| { |
| _r = r; |
| _g = g; |
| _b = b; |
| GfCpack(gf, r, g, b); |
| } |
| |
| |
| |
| void TGraphics::drawLine(const TPointI &a, const TPointI &b) |
| { |
| if (a.x < rasterRegion.x0 && b.x < rasterRegion.x0 || |
| a.x > rasterRegion.x1 && b.x > rasterRegion.x1 || |
| a.y < rasterRegion.y0 && b.y < rasterRegion.y0 || |
| a.y > rasterRegion.y1 && b.y > rasterRegion.y1) |
| return; |
| int v[2]; |
| GfBgnLine(gf); |
| v[0] = a.x; |
| v[1] = a.y; |
| GfV2i(gf, v); |
| v[0] = b.x; |
| v[1] = b.y; |
| GfV2i(gf, v); |
| GfEndLine(gf); |
| } |
| |
| |
| |
| void TGraphics::drawLine(const TPointD &a, const TPointD &b) |
| { |
| if (a.x < rasterRegion.x0 && b.x < rasterRegion.x0 || |
| a.x > rasterRegion.x1 && b.x > rasterRegion.x1 || |
| a.y < rasterRegion.y0 && b.y < rasterRegion.y0 || |
| a.y > rasterRegion.y1 && b.y > rasterRegion.y1) |
| return; |
| double v[2]; |
| GfBgnLine(gf); |
| v[0] = a.x; |
| v[1] = a.y; |
| GfV2d(gf, v); |
| v[0] = b.x; |
| v[1] = b.y; |
| GfV2d(gf, v); |
| GfEndLine(gf); |
| } |
| |
| |
| |
| void TGraphics::beginPolygon() |
| { |
| GfBgnPolygon(gf); |
| } |
| |
| |
| |
| void TGraphics::endPolygon() |
| { |
| GfEndPolygon(gf); |
| } |
| |
| |
| |
| void TGraphics::beginLine() |
| { |
| GfBgnLine(gf); |
| } |
| |
| |
| |
| void TGraphics::endLine() |
| { |
| GfEndLine(gf); |
| } |
| |
| |
| |
| void TGraphics::vertex(const TPointI &a) |
| { |
| int v[2]; |
| v[0] = a.x; |
| v[1] = a.y; |
| GfV2i(gf, v); |
| } |
| |
| |
| |
| void TGraphics::vertex(const TPointD &a) |
| { |
| double v[2]; |
| v[0] = a.x; |
| v[1] = a.y; |
| GfV2d(gf, v); |
| } |
| |
| |
| |
| void TGraphics::drawRect(const TPointI &a, const TPointI &b) |
| { |
| GfRecti(gf, a.x, a.y, b.x, b.y); |
| } |
| |
| |
| |
| void TGraphics::drawRect(const TPointD &a, const TPointD &b) |
| { |
| GfRect(gf, a.x, a.y, b.x, b.y); |
| } |
| |
| |
| |
| void TGraphics::drawRect(const TRectI &rect) |
| { |
| GfRecti(gf, rect.x0, rect.y0, rect.x1, rect.y1); |
| } |
| |
| |
| |
| void TGraphics::drawRect(const TRectD &rect) |
| { |
| GfRect(gf, rect.x0, rect.y0, rect.x1, rect.y1); |
| } |
| |
| |
| |
| void TGraphics::drawArc(const TBezierArc &arc) |
| { |
| int n = 50; |
| beginLine(); |
| for (int i = 0; i <= n; i++) |
| vertex(arc.getPoint((double)i / (double)n)); |
| endLine(); |
| } |
| |
| |
| |
| void TGraphics::drawArc(const TCubicCurve &arc) |
| { |
| int n = 80; |
| beginLine(); |
| for (int i = 0; i <= n; i++) |
| vertex(arc.getPoint((double)i / (double)n)); |
| endLine(); |
| } |
| |
| |
| |
| void TGraphics::drawArcTo(const TPointD &d1, const TPointD &d2, |
| const TPointD &d3) |
| { |
| TPointD oldPoint = currentPoint; |
| currentPoint += d1 + d2 + d3; |
| drawArc(TBezierArc(oldPoint, oldPoint + d1, oldPoint + d1 + d2, currentPoint)); |
| } |
| |
| |
| |
| void TGraphics::drawDiamond(const TPointD &p, double r) |
| { |
| beginPolygon(); |
| vertex(p + TPointD(r, 0)); |
| vertex(p + TPointD(0, r)); |
| vertex(p + TPointD(-r, 0)); |
| vertex(p + TPointD(0, -r)); |
| endPolygon(); |
| } |
| |
| |
| |
| void TGraphics::drawCross(const TPointD &p, double r) |
| { |
| drawLine(p - TPointD(r, r), p + TPointD(r, r)); |
| drawLine(p - TPointD(-r, r), p + TPointD(-r, r)); |
| } |
| |
| |
| |
| void TGraphics::drawSquare(const TPointD &p, double r) |
| { |
| beginLine(); |
| vertex(p + TPointD(-r, -r)); |
| vertex(p + TPointD(-r, r)); |
| vertex(p + TPointD(r, r)); |
| vertex(p + TPointD(r, -r)); |
| vertex(p + TPointD(-r, -r)); |
| endLine(); |
| } |
| |
| |
| |
| void TGraphics::drawArc( |
| const TPointD &p0, |
| const TPointD &p1, |
| const TPointD &p2) |
| { |
| TRectD rect = convert(rasterRegion.enlarge(+10)); |
| |
| TRectD bBox = boundingBox(p0, p1, p2); |
| |
| if (!rect.overlaps(bBox)) { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| return; |
| } |
| |
| double threshold = pixelSize * 0.125; |
| |
| TPointD v = p2 - p0; |
| TPointD u = p1 - p0; |
| TPointD r = rotate90(v); |
| |
| double sqr_tsh = (threshold * threshold) * (v * v); |
| double dist = r * u; |
| |
| if ((dist * dist) > sqr_tsh) { |
| TPointD l1 = 0.5 * (p0 + p1); |
| TPointD r1 = 0.5 * (p1 + p2); |
| TPointD l2 = 0.5 * (l1 + r1); |
| drawArc(p0, l1, l2); |
| drawArc(l2, r1, p2); |
| } else { |
| beginLine(); |
| vertex(p0); |
| vertex(p2); |
| endLine(); |
| } |
| } |
| |
| |
| |
| void TGraphics::drawCircle(TPointD p, double radius) |
| { |
| GfCirc(gf, p.x, p.y, radius); |
| } |
| |
| |
| |
| void TGraphics::fillCircle(TPointD p, double radius) |
| { |
| GfCircf(gf, p.x, p.y, radius); |
| } |
| |
| |
| |
| void TGraphics::rectWrap(int wrap_pixels) |
| { |
| GfRectWrap(gf, wrap_pixels); |
| } |
| |
| |
| |
| void TGraphics::rectWrite(int x0, int y0, int x1, int y1, void *buffer) |
| { |
| GfRectWrite(gf, x0, y0, x1, y1, buffer); |
| } |
| |