/* * Copyright (c) 1987, 1988, 1989 Stanford University * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Stanford not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Stanford makes no representations about * the suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Rubberbanding lines. */ #include #include #include #include RubberLine::RubberLine ( Painter* p, Canvas* c, Coord x0, Coord y0, Coord x1, Coord y1, Coord offx, Coord offy ) : Rubberband(p, c, offx, offy) { fixedx = x0; fixedy = y0; movingx = x1; movingy = y1; trackx = x1; tracky = y1; } void RubberLine::GetOriginal (Coord& x0, Coord& y0, Coord& x1, Coord& y1) { x0 = fixedx; y0 = fixedy; x1 = movingx; y1 = movingy; } void RubberLine::GetCurrent (Coord& x0, Coord& y0, Coord& x1, Coord& y1) { x0 = fixedx; y0 = fixedy; x1 = trackx; y1 = tracky; } void RubberLine::Draw () { Coord x0, y0, x1, y1; if (!drawn) { GetCurrent(x0, y0, x1, y1); output->Line(canvas, x0+offx, y0+offy, x1+offx, y1+offy); drawn = true; } } /*****************************************************************************/ RubberAxis::RubberAxis ( Painter* p, Canvas* c, Coord x0, Coord y0, Coord x1, Coord y1, Coord offx, Coord offy ) : RubberLine(p, c, x0, y0, x1, y1, offx, offy) { /* nothing else to do */ } void RubberAxis::GetCurrent (Coord& x0, Coord& y0, Coord& x1, Coord& y1) { x0 = fixedx; y0 = fixedy; if (abs(fixedx - trackx) < abs(fixedy - tracky)) { x1 = fixedx; y1 = tracky; } else { x1 = trackx; y1 = fixedy; } } /*****************************************************************************/ SlidingLine::SlidingLine ( Painter* p, Canvas* c, Coord x0, Coord y0, Coord x1, Coord y1, Coord rfx, Coord rfy, Coord offx, Coord offy ) : RubberLine(p, c, x0, y0, x1, y1, offx, offy) { refx = rfx; refy = rfy; trackx = rfx; tracky = rfy; } void SlidingLine::GetCurrent (Coord& x0, Coord& y0, Coord& x1, Coord& y1) { Coord dx = trackx - refx; Coord dy = tracky - refy; x0 = fixedx + dx; y0 = fixedy + dy; x1 = movingx + dx; y1 = movingy + dy; } /*****************************************************************************/ ScalingLine::ScalingLine ( Painter* p, Canvas* c, Coord x0, Coord y0, Coord x1, Coord y1, Coord cx, Coord cy, Coord offx, Coord offy ) : RubberLine(p, c, x0, y0, x1, y1, offx, offy) { centerx = cx; centery = cy; width = abs(x0 - x1); height = abs(y0 - y1); } void ScalingLine::GetCurrent (Coord& x0, Coord& y0, Coord& x1, Coord& y1) { double factor = CurrentScaling(); x0 = round(double(fixedx - centerx) * factor) + centerx; y0 = round(double(fixedy - centery) * factor) + centery; x1 = round(double(movingx - centerx) * factor) + centerx; y1 = round(double(movingy - centery) * factor) + centery; } float ScalingLine::CurrentScaling () { Coord dx, dy; double factor = 1; dx = abs(trackx - centerx); dy = abs(tracky - centery); if (width != 0 && dx > dy) { factor = double(2 * dx) / double(width); } else if (height != 0) { factor = double(2 * dy) / double(height); } return factor; } /*****************************************************************************/ void RotatingLine::Transform ( Coord& x, Coord& y, double a0, double a1, double b0, double b1, double c0, double c1 ) { double tx, ty; tx = double(x); ty = double(y); x = round(a0*tx + b0*ty + c0); y = round(a1*tx + b1*ty + c1); } RotatingLine::RotatingLine ( Painter* p, Canvas* c, Coord x0, Coord y0, Coord x1, Coord y1, Coord cx, Coord cy, Coord rfx, Coord rfy, Coord offx, Coord offy ) : RubberLine(p, c, x0, y0, x1, y1, offx, offy) { centerx = cx; centery = cy; refx = rfx; refy = rfy; } void RotatingLine::GetCurrent (Coord& x0, Coord& y0, Coord& x1, Coord& y1) { double sin, cos, hprod, dx1, dy1, dx2, dy2; x0 = fixedx - centerx; y0 = fixedy - centery; x1 = movingx - centerx; y1 = movingy - centery; dx1 = double(refx - centerx); dy1 = double(refy - centery); dx2 = double(trackx - centerx); dy2 = double(tracky - centery); hprod = sqrt((dx1*dx1 + dy1*dy1) * (dx2*dx2 + dy2*dy2)); if (hprod != 0.0) { cos = (dx1*dx2 + dy1*dy2) / hprod; sin = (dx1*dy2 - dx2*dy1) / hprod; Transform(x0, y0, cos, sin, -sin, cos, 0.0, 0.0); Transform(x1, y1, cos, sin, -sin, cos, 0.0, 0.0); } x0 += centerx; y0 += centery; x1 += centerx; y1 += centery; } float RotatingLine::OriginalAngle () { Coord x0, y0, x1, y1; GetOriginal(x0, y0, x1, y1); return Angle(x0, y0, x1, y1); } float RotatingLine::CurrentAngle () { Coord x0, y0, x1, y1; GetCurrent(x0, y0, x1, y1); return Angle(x0, y0, x1, y1); }