diff options
Diffstat (limited to 'kig/objects/line_imp.cc')
-rw-r--r-- | kig/objects/line_imp.cc | 571 |
1 files changed, 0 insertions, 571 deletions
diff --git a/kig/objects/line_imp.cc b/kig/objects/line_imp.cc deleted file mode 100644 index 4223000b..00000000 --- a/kig/objects/line_imp.cc +++ /dev/null @@ -1,571 +0,0 @@ -// Copyright (C) 2002 Dominique Devriese <devriese@kde.org> - -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -// 02110-1301, USA. - -#include "line_imp.h" - -#include "bogus_imp.h" -#include "point_imp.h" - -#include "../misc/rect.h" -#include "../misc/common.h" -#include "../misc/kigtransform.h" -#include "../misc/kigpainter.h" -#include "../kig/kig_view.h" - -#include <tdelocale.h> - -#include <cmath> -using namespace std; - -AbstractLineImp::AbstractLineImp( const Coordinate& a, const Coordinate& b ) - : mdata( a, b ) -{ -} - -AbstractLineImp::~AbstractLineImp() -{ -} - -bool AbstractLineImp::inRect( const Rect& r, int width, const KigWidget& w ) const -{ - return lineInRect( r, mdata.a, mdata.b, width, this, w ); -} - -const uint AbstractLineImp::numberOfProperties() const -{ - return Parent::numberOfProperties() + 2; -} - -const ObjectImpType* AbstractLineImp::impRequirementForProperty( uint which ) const -{ - if ( which < Parent::numberOfProperties() ) - return Parent::impRequirementForProperty( which ); - else return AbstractLineImp::stype(); -} - -const char* AbstractLineImp::iconForProperty( uint which ) const -{ - if ( which < Parent::numberOfProperties() ) - return Parent::iconForProperty( which ); - if ( which == Parent::numberOfProperties() ) - return "slope"; // slope - if ( which == Parent::numberOfProperties() + 1 ) - return "kig_text"; // equation - else assert( false ); - return ""; -} - -ObjectImp* AbstractLineImp::property( uint which, const KigDocument& w ) const -{ - if ( which < Parent::numberOfProperties() ) - return Parent::property( which, w ); - if ( which == Parent::numberOfProperties() ) - return new DoubleImp( slope() ); - if ( which == Parent::numberOfProperties() + 1 ) - return new StringImp( equationString() ); - else assert( false ); - return new InvalidImp; -} - -const QCStringList AbstractLineImp::propertiesInternalNames() const -{ - QCStringList l = Parent::propertiesInternalNames(); - l << "slope"; - l << "equation"; - assert( l.size() == AbstractLineImp::numberOfProperties() ); - return l; -} - -const QCStringList AbstractLineImp::properties() const -{ - QCStringList l = Parent::properties(); - l << I18N_NOOP( "Slope" ); - l << I18N_NOOP( "Equation" ); - assert( l.size() == AbstractLineImp::numberOfProperties() ); - return l; -} - -const uint SegmentImp::numberOfProperties() const -{ - return Parent::numberOfProperties() + 4; -} - -const QCStringList SegmentImp::propertiesInternalNames() const -{ - QCStringList s = Parent::propertiesInternalNames(); - s << "length"; - s << "mid-point"; - s << "end-point-A"; - s << "end-point-B"; - assert( s.size() == SegmentImp::numberOfProperties() ); - return s; -} - -const QCStringList SegmentImp::properties() const -{ - QCStringList s = Parent::properties(); - s << I18N_NOOP( "Length" ); - s << I18N_NOOP( "Mid Point" ); - s << I18N_NOOP( "First End Point" ); - s << I18N_NOOP( "Second End Point" ); - assert( s.size() == SegmentImp::numberOfProperties() ); - return s; -} - -const ObjectImpType* SegmentImp::impRequirementForProperty( uint which ) const -{ - if ( which < Parent::numberOfProperties() ) - return Parent::impRequirementForProperty( which ); - else return SegmentImp::stype(); -} - -const char* SegmentImp::iconForProperty( uint which ) const -{ - int pnum = 0; - if ( which < Parent::numberOfProperties() ) - return Parent::iconForProperty( which ); - else if ( which == Parent::numberOfProperties() + pnum++ ) - return "distance"; // length - else if ( which == Parent::numberOfProperties() + pnum++ ) - return "segment_midpoint"; // mid point - else if ( which == Parent::numberOfProperties() + pnum++ ) - return "endpoint1"; // mid point - else if ( which == Parent::numberOfProperties() + pnum++ ) - return "endpoint2"; // mid point - else assert( false ); - return ""; -} - -ObjectImp* SegmentImp::property( uint which, const KigDocument& w ) const -{ - int pnum = 0; - - if ( which < Parent::numberOfProperties() ) - return Parent::property( which, w ); - else if ( which == Parent::numberOfProperties() + pnum++ ) - return new DoubleImp( mdata.dir().length() ); - else if ( which == Parent::numberOfProperties() + pnum++ ) - return new PointImp( ( mdata.a + mdata.b ) / 2 ); - else if ( which == Parent::numberOfProperties() + pnum++ ) - return new PointImp( mdata.a ); - else if ( which == Parent::numberOfProperties() + pnum++ ) - return new PointImp( mdata.b ); - else assert( false ); - return new InvalidImp; -} - -double AbstractLineImp::slope() const -{ - Coordinate diff = mdata.dir(); - return diff.y / diff.x; -} - -const TQString AbstractLineImp::equationString() const -{ - Coordinate p = mdata.a; - Coordinate q = mdata.b; - - double m = ( q.y - p.y ) / ( q.x - p.x ); - double r = - ( q.y - p.y ) * p.x / ( q.x - p.x ) + p.y; - - TQString ret = TQString::fromUtf8( "y = %1x " ) + - TQString::fromUtf8( r > 0 ? "+" : "-" ) + - TQString::fromUtf8( " %2" ); - - ret = ret.arg( m, 0, 'g', 3 ); - ret = ret.arg( abs( r ), 0, 'g', 3 ); - - return ret; -} - -void SegmentImp::draw( KigPainter& p ) const -{ - p.drawSegment( mdata ); -} - -bool SegmentImp::contains( const Coordinate& p, int width, const KigWidget& w ) const -{ - return internalContainsPoint( p, w.screenInfo().normalMiss( width ) ); -} - -void RayImp::draw( KigPainter& p ) const -{ - p.drawRay( mdata ); -} - -bool RayImp::contains( const Coordinate& p, int width, const KigWidget& w ) const -{ - return internalContainsPoint( p, w.screenInfo().normalMiss( width ) ); -} - -void LineImp::draw( KigPainter& p ) const -{ - p.drawLine( mdata ); -} - -bool LineImp::contains( const Coordinate& p, int width, const KigWidget& w ) const -{ - return internalContainsPoint( p, w.screenInfo().normalMiss( width ) ); -} - -SegmentImp::SegmentImp( const Coordinate& a, const Coordinate& b ) - : AbstractLineImp( a, b ) -{ -} - -RayImp::RayImp( const Coordinate& a, const Coordinate& b ) - : AbstractLineImp( a, b ) -{ -} - -LineImp::LineImp( const Coordinate& a, const Coordinate& b ) - : AbstractLineImp( a, b ) -{ -} - -SegmentImp* SegmentImp::copy() const -{ - return new SegmentImp( mdata ); -} - -RayImp* RayImp::copy() const -{ - return new RayImp( mdata ); -} - -LineImp* LineImp::copy() const -{ - return new LineImp( mdata ); -} - -const Coordinate SegmentImp::getPoint( double param, const KigDocument& ) const -{ - return mdata.a + mdata.dir()*param; -} - -double SegmentImp::getParam( const Coordinate& p, const KigDocument& ) const -{ - Coordinate pt = calcPointOnPerpend( data(), p ); - pt = calcIntersectionPoint( data(), LineData( p, pt ) ); - // if pt is over the end of the segment ( i.e. it's on the line - // which the segment is a part of, but not of the segment itself..; - // ) we set it to one of the end points of the segment... - if ((pt - mdata.a).length() > mdata.dir().length() ) - pt = mdata.b; - else if ( (pt- mdata.b).length() > mdata.dir().length() ) - pt = mdata.a; - if (mdata.b == mdata.a) return 0; - return ((pt - mdata.a).length())/(mdata.dir().length()); -} - -LineData AbstractLineImp::data() const -{ - return mdata; -} - -const Coordinate RayImp::getPoint( double param, const KigDocument& ) const -{ - param = 1.0/param - 1.0; - return mdata.a + mdata.dir()*param; -} - -double RayImp::getParam( const Coordinate& p, const KigDocument& ) const -{ - const LineData ld = data(); - Coordinate pt = calcPointOnPerpend( ld, p ); - pt = calcIntersectionPoint( ld, LineData( p, pt )); - // if pt is over the end of the ray ( i.e. it's on the line - // which the ray is a part of, but not of the ray itself..; - // ) we set it to the start point of the ray... - Coordinate dir = ld.dir(); - pt -= ld.a; - double param; - if ( dir.x != 0 ) param = pt.x / dir.x; - else if ( dir.y != 0 ) param = pt.y / dir.y; - else param = 0.; - if ( param < 0. ) param = 0.; - - // mp: let's try with 1/(x+1), this reverses the mapping, but - // should allow to take advantage of the tightness of floating point - // numbers near zero, in order to get more possible positions near - // infinity - - param = 1./( param + 1. ); - - assert( param >= 0. && param <= 1. ); - return param; -} - -const Coordinate LineImp::getPoint( double p, const KigDocument& ) const -{ - // inspired upon KSeg - - // we need to spread the points over the line, it should also come near - // the (infinite) end of the line, but most points should be near - // the two points we contain... - if ( p <= 0. ) p = 1e-6; - if ( p >= 1. ) p = 1 - 1e-6; - p = 2*p - 1; - if (p > 0) p = p/(1 - p); - else p = p/(1 + p); -// p *= 1024; // such multiplying factor could be useful in order to - // have more points near infinity, at the expense of - // points near ma and mb - return mdata.a + p*mdata.dir(); -} - -double LineImp::getParam( const Coordinate& point, const KigDocument& ) const -{ - // somewhat the reverse of getPoint, although it also supports - // points not on the line... - - Coordinate pa = point - mdata.a; - Coordinate ba = mdata.dir(); - double balsq = ba.x*ba.x + ba.y*ba.y; - assert (balsq > 0); - - double p = (pa.x*ba.x + pa.y*ba.y)/balsq; -// p /= 1024; - if (p > 0) p = p/(1+p); - else p = p/(1-p); - - return 0.5*(p + 1); -} - -ObjectImp* SegmentImp::transform( const Transformation& t ) const -{ - if ( ! t.isAffine() ) /* we need to check the position of the two points */ - { - if ( t.getProjectiveIndicator( mdata.a ) * - t.getProjectiveIndicator( mdata.b ) < 0 ) - return new InvalidImp(); - } - Coordinate na = t.apply( mdata.a ); - Coordinate nb = t.apply( mdata.b ); - if( na.valid() && nb.valid() ) return new SegmentImp( na, nb ); - else return new InvalidImp(); -} - -ObjectImp* LineImp::transform( const Transformation& t ) const -{ - Coordinate na = t.apply( mdata.a ); - Coordinate nb = t.apply( mdata.b ); - if ( na.valid() && nb.valid() ) return new LineImp( na, nb ); - else return new InvalidImp(); -} - -ObjectImp* RayImp::transform( const Transformation& t ) const -{ - if ( ! t.isAffine() ) /* we need to check the position of the two points */ - { - double pa = t.getProjectiveIndicator( mdata.a ); - double pb = t.getProjectiveIndicator( mdata.b ); - if ( pa < 0 ) pb = -pb; - if ( pb < fabs (pa) ) return new InvalidImp(); - Coordinate na = t.apply( mdata.a ); - Coordinate nb = t.apply0( mdata.b - mdata.a ); - if ( na.valid() && nb.valid() ) return new SegmentImp( na, nb ); - else return new InvalidImp(); - } - Coordinate na = t.apply( mdata.a ); - Coordinate nb = t.apply( mdata.b ); - if ( na.valid() && nb.valid() ) return new RayImp( na, nb ); - else return new InvalidImp(); -} - -AbstractLineImp::AbstractLineImp( const LineData& d ) - : mdata( d ) -{ -} - -SegmentImp::SegmentImp( const LineData& d ) - : AbstractLineImp( d ) -{ -} - -RayImp::RayImp( const LineData& d ) - : AbstractLineImp( d ) -{ -} - -LineImp::LineImp( const LineData& d ) - : AbstractLineImp( d ) -{ -} - -double SegmentImp::length() const -{ - return mdata.length(); -} - -void SegmentImp::visit( ObjectImpVisitor* vtor ) const -{ - vtor->visit( this ); -} - -void RayImp::visit( ObjectImpVisitor* vtor ) const -{ - vtor->visit( this ); -} - -void LineImp::visit( ObjectImpVisitor* vtor ) const -{ - vtor->visit( this ); -} - -bool AbstractLineImp::equals( const ObjectImp& rhs ) const -{ - return rhs.type() == type() && - static_cast<const AbstractLineImp&>( rhs ).data() == data(); -} - -const ObjectImpType* AbstractLineImp::stype() -{ - static const ObjectImpType t( - Parent::stype(), "line", I18N_NOOP( "line" ), - I18N_NOOP( "Select a Line" ), 0, 0, 0, 0, 0, 0, 0 ); - return &t; -} - -const ObjectImpType* LineImp::stype() -{ - static const ObjectImpType t( - Parent::stype(), "line", - I18N_NOOP( "line" ), - I18N_NOOP( "Select this line" ), - I18N_NOOP( "Select line %1" ), - I18N_NOOP( "Remove a Line" ), - I18N_NOOP( "Add a Line" ), - I18N_NOOP( "Move a Line" ), - I18N_NOOP( "Attach to this line" ), - I18N_NOOP( "Show a Line" ), - I18N_NOOP( "Hide a Line" ) - ); - return &t; -} - -const ObjectImpType* SegmentImp::stype() -{ - static const ObjectImpType t( - Parent::stype(), "segment", - I18N_NOOP( "segment" ), - I18N_NOOP( "Select this segment" ), - I18N_NOOP( "Select segment %1" ), - I18N_NOOP( "Remove a Segment" ), - I18N_NOOP( "Add a Segment" ), - I18N_NOOP( "Move a Segment" ), - I18N_NOOP( "Attach to this segment" ), - I18N_NOOP( "Show a Segment" ), - I18N_NOOP( "Hide a Segment" ) - ); - return &t; -} - -const ObjectImpType* RayImp::stype() -{ - static const ObjectImpType t( - Parent::stype(), "ray", - I18N_NOOP( "half-line" ), - I18N_NOOP( "Select this half-line" ), - I18N_NOOP( "Select half-line %1" ), - I18N_NOOP( "Remove a Half-Line" ), - I18N_NOOP( "Add a Half-Line" ), - I18N_NOOP( "Move a Half-Line" ), - I18N_NOOP( "Attach to this half-line" ), - I18N_NOOP( "Show a Half-Line" ), - I18N_NOOP( "Hide a Half-Line" ) - ); - return &t; -} - -const ObjectImpType* SegmentImp::type() const -{ - return SegmentImp::stype(); -} - -const ObjectImpType* RayImp::type() const -{ - return RayImp::stype(); -} - -const ObjectImpType* LineImp::type() const -{ - return LineImp::stype(); -} - -bool SegmentImp::containsPoint( const Coordinate& p, const KigDocument& ) const -{ - return internalContainsPoint( p, test_threshold ); -} - -bool SegmentImp::internalContainsPoint( const Coordinate& p, double threshold ) const -{ - return isOnSegment( p, mdata.a, mdata.b, threshold ); -} - -bool RayImp::containsPoint( const Coordinate& p, const KigDocument& ) const -{ - return internalContainsPoint( p, test_threshold ); -} - -bool RayImp::internalContainsPoint( const Coordinate& p, double threshold ) const -{ - return isOnRay( p, mdata.a, mdata.b, threshold ); -} - -bool LineImp::containsPoint( const Coordinate& p, const KigDocument& ) const -{ - return internalContainsPoint( p, test_threshold ); -} - -bool LineImp::internalContainsPoint( const Coordinate& p, double threshold ) const -{ - return isOnLine( p, mdata.a, mdata.b, threshold ); -} - -bool AbstractLineImp::isPropertyDefinedOnOrThroughThisImp( uint which ) const -{ - int pnum = 0; - - if ( which < Parent::numberOfProperties() ) - return Parent::isPropertyDefinedOnOrThroughThisImp( which ); - else if ( which == Parent::numberOfProperties() + pnum++ ) - return false; - else if ( which == Parent::numberOfProperties() + pnum++ ) - return true; - else if ( which == Parent::numberOfProperties() + pnum++ ) - return true; - else if ( which == Parent::numberOfProperties() + pnum++ ) - return true; - else assert( false ); - return false; -} - -Rect SegmentImp::surroundingRect() const -{ - return Rect( mdata.a, mdata.b ); -} - -Rect RayImp::surroundingRect() const -{ - return Rect::invalidRect(); -} - -Rect LineImp::surroundingRect() const -{ - return Rect::invalidRect(); -} |