1 // Copyright (C) 2003 Dominique Devriese <devriese@kde.org>
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18 #include "special_constructors.h"
20 #include "calcpaths.h"
22 #include "conic-common.h"
23 #include "guiaction.h"
24 #include "kigpainter.h"
26 #include "../kig/kig_part.h"
27 #include "../modes/construct_mode.h"
28 #include "../objects/bogus_imp.h"
29 #include "../objects/centerofcurvature_type.h"
30 #include "../objects/circle_imp.h"
31 #include "../objects/conic_imp.h"
32 #include "../objects/conic_types.h"
33 #include "../objects/cubic_imp.h"
34 #include "../objects/intersection_types.h"
35 #include "../objects/inversion_type.h"
36 #include "../objects/line_imp.h"
37 #include "../objects/line_type.h"
38 #include "../objects/locus_imp.h"
39 #include "../objects/object_calcer.h"
40 #include "../objects/object_drawer.h"
41 #include "../objects/object_factory.h"
42 #include "../objects/object_holder.h"
43 #include "../objects/object_imp.h"
44 #include "../objects/object_type.h"
45 #include "../objects/other_imp.h"
46 #include "../objects/other_type.h"
47 #include "../objects/point_imp.h"
48 #include "../objects/point_type.h"
49 #include "../objects/polygon_imp.h"
50 #include "../objects/polygon_type.h"
51 #include "../objects/tangent_type.h"
52 #include "../objects/text_imp.h"
53 #include "../objects/transform_types.h"
62 class ConicConicIntersectionConstructor
63 : public StandardConstructorBase
68 ConicConicIntersectionConstructor();
69 ~ConicConicIntersectionConstructor();
71 void drawprelim( const ObjectDrawer
& drawer
, KigPainter
& p
, const std::vector
<ObjectCalcer
*>& parents
,
72 const KigDocument
& ) const;
73 std::vector
<ObjectHolder
*> build( const std::vector
<ObjectCalcer
*>& os
, KigDocument
& d
, KigWidget
& w
) const;
74 void plug( KigPart
* doc
, KigGUIAction
* kact
);
76 bool isTransform() const;
79 class ConicLineIntersectionConstructor
80 : public MultiObjectTypeConstructor
83 ConicLineIntersectionConstructor();
84 ~ConicLineIntersectionConstructor();
87 class ArcLineIntersectionConstructor
88 : public MultiObjectTypeConstructor
91 ArcLineIntersectionConstructor();
92 ~ArcLineIntersectionConstructor();
95 ConicRadicalConstructor::ConicRadicalConstructor()
96 : StandardConstructorBase(
97 I18N_NOOP( "Radical Lines for Conics" ),
98 I18N_NOOP( "The lines constructed through the intersections "
99 "of two conics. This is also defined for "
100 "non-intersecting conics." ),
101 "conicsradicalline", mparser
),
102 mtype( ConicRadicalType::instance() ),
103 mparser( mtype
->argsParser().without( IntImp::stype() ) )
107 ConicRadicalConstructor::~ConicRadicalConstructor()
111 void ConicRadicalConstructor::drawprelim(
112 const ObjectDrawer
& drawer
, KigPainter
& p
, const std::vector
<ObjectCalcer
*>& parents
, const KigDocument
& doc
) const
114 if ( parents
.size() == 2 && parents
[0]->imp()->inherits( ConicImp::stype() ) &&
115 parents
[1]->imp()->inherits( ConicImp::stype() ) )
118 std::transform( parents
.begin(), parents
.end(),
119 std::back_inserter( args
), std::mem_fun( &ObjectCalcer::imp
) );
120 for ( int i
= -1; i
< 2; i
+= 2 )
123 IntImp
zeroindex( 1 );
124 args
.push_back( &root
);
125 args
.push_back( &zeroindex
);
126 ObjectImp
* data
= mtype
->calc( args
, doc
);
127 drawer
.draw( *data
, p
, true );
128 delete data
; data
= 0;
135 std::vector
<ObjectHolder
*> ConicRadicalConstructor::build( const std::vector
<ObjectCalcer
*>& os
, KigDocument
&, KigWidget
& ) const
138 std::vector
<ObjectHolder
*> ret
;
139 ObjectCalcer
* zeroindexcalcer
= new ObjectConstCalcer( new IntImp( 1 ) );
140 for ( int i
= -1; i
< 2; i
+= 2 )
142 std::vector
<ObjectCalcer
*> args
;
143 std::copy( os
.begin(), os
.end(), back_inserter( args
) );
144 args
.push_back( new ObjectConstCalcer( new IntImp( i
) ) );
145 // we use only one zeroindex dataobject, so that if you switch one
146 // radical line around, then the other switches along..
147 args
.push_back( zeroindexcalcer
);
149 new ObjectHolder( new ObjectTypeCalcer( mtype
, args
) ) );
154 static const struct ArgsParser::spec argsspecpp
[] =
156 { PointImp::stype(), I18N_NOOP( "Moving Point" ),
157 I18N_NOOP( "Select the moving point, which will be moved around while drawing the locus..." ), false },
158 { PointImp::stype(), I18N_NOOP( "Following Point" ),
159 I18N_NOOP( "Select the following point, whose locations the locus will be drawn through..." ), true }
162 LocusConstructor::LocusConstructor()
163 : StandardConstructorBase( I18N_NOOP( "Locus" ), I18N_NOOP( "A locus" ),
164 "locus", margsparser
),
165 margsparser( argsspecpp
, 2 )
169 LocusConstructor::~LocusConstructor()
173 void LocusConstructor::drawprelim( const ObjectDrawer
& drawer
, KigPainter
& p
, const std::vector
<ObjectCalcer
*>& parents
,
174 const KigDocument
& ) const
176 // this function is rather ugly, but it is necessary to do it this
177 // way in order to play nice with Kig's design..
179 if ( parents
.size() != 2 ) return;
180 const ObjectTypeCalcer
* constrained
= dynamic_cast<ObjectTypeCalcer
*>( parents
.front() );
181 const ObjectCalcer
* moving
= parents
.back();
182 if ( ! constrained
|| ! constrained
->type()->inherits( ObjectType::ID_ConstrainedPointType
) )
184 // moving is in fact the constrained point.. swap them..
185 moving
= parents
.front();
186 constrained
= dynamic_cast<const ObjectTypeCalcer
*>( parents
.back() );
187 assert( constrained
);
189 assert( constrained
->type()->inherits( ObjectType::ID_ConstrainedPointType
) );
191 const ObjectImp
* oimp
= constrained
->parents().back()->imp();
192 if( !oimp
->inherits( CurveImp::stype() ) )
193 oimp
= constrained
->parents().front()->imp();
194 assert( oimp
->inherits( CurveImp::stype() ) );
195 const CurveImp
* cimp
= static_cast<const CurveImp
*>( oimp
);
197 ObjectHierarchy
hier( constrained
, moving
);
199 LocusImp
limp( cimp
->copy(), hier
);
200 drawer
.draw( limp
, p
, true );
203 const int LocusConstructor::wantArgs(
204 const std::vector
<ObjectCalcer
*>& os
, const KigDocument
&, const KigWidget
&
207 int ret
= margsparser
.check( os
);
208 if ( ret
== ArgsParser::Invalid
) return ret
;
209 else if ( os
.size() != 2 ) return ret
;
210 if ( dynamic_cast<ObjectTypeCalcer
*>( os
.front() ) &&
211 static_cast<ObjectTypeCalcer
*>( os
.front() )->type()->inherits( ObjectType::ID_ConstrainedPointType
) )
213 std::set
<ObjectCalcer
*> children
= getAllChildren( os
.front() );
214 return children
.find( os
.back() ) != children
.end() ? ret
: ArgsParser::Invalid
;
216 if ( dynamic_cast<ObjectTypeCalcer
*>( os
.back() ) &&
217 static_cast<ObjectTypeCalcer
*>( os
.back() )->type()->inherits( ObjectType::ID_ConstrainedPointType
) )
219 std::set
<ObjectCalcer
*> children
= getAllChildren( os
.back() );
220 return children
.find( os
.front() ) != children
.end() ? ret
: ArgsParser::Invalid
;
222 return ArgsParser::Invalid
;
225 std::vector
<ObjectHolder
*> LocusConstructor::build( const std::vector
<ObjectCalcer
*>& parents
, KigDocument
&, KigWidget
& ) const
227 std::vector
<ObjectHolder
*> ret
;
228 assert( parents
.size() == 2 );
230 ObjectTypeCalcer
* constrained
= dynamic_cast<ObjectTypeCalcer
*>( parents
.front() );
231 ObjectCalcer
* moving
= parents
.back();
232 if ( ! constrained
|| ! constrained
->type()->inherits( ObjectType::ID_ConstrainedPointType
) )
234 // moving is in fact the constrained point.. swap them..
235 moving
= parents
.front();
236 constrained
= dynamic_cast<ObjectTypeCalcer
*>( parents
.back() );
237 assert( constrained
);
239 assert( constrained
->type()->inherits( ObjectType::ID_ConstrainedPointType
) );
241 ret
.push_back( ObjectFactory::instance()->locus( constrained
, moving
) );
245 QString
LocusConstructor::useText( const ObjectCalcer
& o
, const std::vector
<ObjectCalcer
*>& os
,
246 const KigDocument
&, const KigWidget
& ) const
248 if ( dynamic_cast<const ObjectTypeCalcer
*>( &o
) &&
249 static_cast<const ObjectTypeCalcer
&>( o
).type()->inherits( ObjectType::ID_ConstrainedPointType
) &&
250 ( os
.empty() || !dynamic_cast<ObjectTypeCalcer
*>( os
[0] ) ||
251 !static_cast<const ObjectTypeCalcer
*>( os
[0] )->type()->inherits( ObjectType::ID_ConstrainedPointType
) )
252 ) return i18n( "Moving Point" );
253 else return i18n( "Dependent Point" );
256 void ConicRadicalConstructor::plug( KigPart
*, KigGUIAction
* )
260 void LocusConstructor::plug( KigPart
*, KigGUIAction
* )
264 bool ConicRadicalConstructor::isTransform() const
266 return mtype
->isTransform();
269 bool LocusConstructor::isTransform() const
275 * generic polygon constructor
278 PolygonBNPTypeConstructor::PolygonBNPTypeConstructor()
279 : mtype( PolygonBNPType::instance() )
283 PolygonBNPTypeConstructor::~PolygonBNPTypeConstructor()
287 const QString
PolygonBNPTypeConstructor::descriptiveName() const
289 return i18n("Polygon by Its Vertices");
292 const QString
PolygonBNPTypeConstructor::description() const
294 return i18n("Construct a polygon by giving its vertices");
297 const QCString
PolygonBNPTypeConstructor::iconFileName( const bool ) const
302 const bool PolygonBNPTypeConstructor::isAlreadySelectedOK(
303 const std::vector
<ObjectCalcer
*>& os
, const int& pos
) const
305 if ( pos
== 0 && os
.size() >= 3 ) return true;
309 const int PolygonBNPTypeConstructor::wantArgs( const std::vector
<ObjectCalcer
*>& os
,
311 const KigWidget
& ) const
313 int count
=os
.size() - 1;
315 for ( int i
= 0; i
<= count
; i
++ )
317 if ( ! ( os
[i
]->imp()->inherits( PointImp::stype() ) ) ) return ArgsParser::Invalid
;
319 if ( count
< 3 ) return ArgsParser::Valid
;
320 if ( os
[0] == os
[count
] ) return ArgsParser::Complete
;
321 return ArgsParser::Valid
;
324 void PolygonBNPTypeConstructor::handleArgs(
325 const std::vector
<ObjectCalcer
*>& os
, KigPart
& d
,
328 std::vector
<ObjectHolder
*> bos
= build( os
, d
.document(), v
);
329 for ( std::vector
<ObjectHolder
*>::iterator i
= bos
.begin();
330 i
!= bos
.end(); ++i
)
332 (*i
)->calc( d
.document() );
338 void PolygonBNPTypeConstructor::handlePrelim(
339 KigPainter
& p
, const std::vector
<ObjectCalcer
*>& os
,
340 const KigDocument
& d
, const KigWidget
&
343 uint count
= os
.size();
344 if ( count
< 2 ) return;
346 for ( uint i
= 0; i
< count
; i
++ )
348 assert ( os
[i
]->imp()->inherits( PointImp::stype() ) );
351 std::vector
<ObjectCalcer
*> args
= os
;
352 p
.setBrushStyle( Qt::NoBrush
);
353 p
.setBrushColor( Qt::red
);
354 p
.setPen( QPen ( Qt::red
, 1) );
355 p
.setWidth( -1 ); // -1 means the default width for the object being
358 ObjectDrawer
drawer( Qt::red
);
359 drawprelim( drawer
, p
, args
, d
);
362 QString
PolygonBNPTypeConstructor::useText( const ObjectCalcer
&, const std::vector
<ObjectCalcer
*>& os
,
363 const KigDocument
&, const KigWidget
& ) const
366 return i18n("... with this vertex (click on the first vertex to terminate construction)");
367 else return i18n("Construct a polygon with this vertex");
370 QString
PolygonBNPTypeConstructor::selectStatement(
371 const std::vector
<ObjectCalcer
*>&, const KigDocument
&,
372 const KigWidget
& ) const
374 return i18n("Select a point to be a vertex of the new polygon...");
377 void PolygonBNPTypeConstructor::drawprelim( const ObjectDrawer
& drawer
, KigPainter
& p
, const std::vector
<ObjectCalcer
*>& parents
,
378 const KigDocument
& ) const
380 if ( parents
.size() < 2 ) return;
382 std::vector
<Coordinate
> points
;
384 for ( uint i
= 0; i
< parents
.size(); ++i
)
386 const Coordinate vertex
=
387 static_cast<const PointImp
*>( parents
[i
]->imp() )->coordinate();
388 points
.push_back( vertex
);
391 if ( parents
.size() == 2 )
393 SegmentImp segment
= SegmentImp( points
[0], points
[1] );
394 drawer
.draw( segment
, p
, true );
396 PolygonImp polygon
= PolygonImp( points
);
397 drawer
.draw( polygon
, p
, true );
401 std::vector
<ObjectHolder
*> PolygonBNPTypeConstructor::build( const std::vector
<ObjectCalcer
*>& parents
, KigDocument
&, KigWidget
& ) const
403 uint count
= parents
.size() - 1;
404 assert ( count
>= 3 );
405 std::vector
<ObjectCalcer
*> args
;
406 for ( uint i
= 0; i
< count
; ++i
) args
.push_back( parents
[i
] );
407 ObjectTypeCalcer
* calcer
= new ObjectTypeCalcer( mtype
, args
);
408 ObjectHolder
* h
= new ObjectHolder( calcer
);
409 std::vector
<ObjectHolder
*> ret
;
414 void PolygonBNPTypeConstructor::plug( KigPart
*, KigGUIAction
* )
418 bool PolygonBNPTypeConstructor::isTransform() const
424 * construction of polygon vertices
427 static const struct ArgsParser::spec argsspecpv
[] =
429 { PolygonImp::stype(), I18N_NOOP( "Polygon" ),
430 I18N_NOOP( "Construct the vertices of this polygon..." ), true }
433 PolygonVertexTypeConstructor::PolygonVertexTypeConstructor()
434 : StandardConstructorBase( I18N_NOOP( "Vertices of a Polygon" ),
435 I18N_NOOP( "The vertices of a polygon." ),
436 "polygonvertices", margsparser
),
437 mtype( PolygonVertexType::instance() ),
438 margsparser( argsspecpv
, 1 )
442 PolygonVertexTypeConstructor::~PolygonVertexTypeConstructor()
446 void PolygonVertexTypeConstructor::drawprelim( const ObjectDrawer
& drawer
, KigPainter
& p
, const std::vector
<ObjectCalcer
*>& parents
,
447 const KigDocument
& ) const
449 if ( parents
.size() != 1 ) return;
451 const PolygonImp
* polygon
= dynamic_cast<const PolygonImp
*>( parents
.front()->imp() );
452 const std::vector
<Coordinate
> points
= polygon
->points();
454 int sides
= points
.size();
455 for ( int i
= 0; i
< sides
; ++i
)
457 PointImp point
= PointImp( points
[i
] );
458 drawer
.draw( point
, p
, true );
462 std::vector
<ObjectHolder
*> PolygonVertexTypeConstructor::build( const std::vector
<ObjectCalcer
*>& parents
, KigDocument
&, KigWidget
& ) const
464 std::vector
<ObjectHolder
*> ret
;
465 assert( parents
.size() == 1 );
466 const PolygonImp
* polygon
= dynamic_cast<const PolygonImp
*>( parents
.front()->imp() );
467 const std::vector
<Coordinate
> points
= polygon
->points();
469 int sides
= points
.size();
471 for ( int i
= 0; i
< sides
; ++i
)
473 ObjectConstCalcer
* d
= new ObjectConstCalcer( new IntImp( i
) );
474 std::vector
<ObjectCalcer
*> args( parents
);
476 ret
.push_back( new ObjectHolder( new ObjectTypeCalcer( mtype
, args
) ) );
481 void PolygonVertexTypeConstructor::plug( KigPart
*, KigGUIAction
* )
485 bool PolygonVertexTypeConstructor::isTransform() const
491 * construction of polygon sides
494 static const struct ArgsParser::spec argsspecps
[] =
496 { PolygonImp::stype(), I18N_NOOP( "Polygon" ),
497 I18N_NOOP( "Construct the sides of this polygon..." ), false }
500 PolygonSideTypeConstructor::PolygonSideTypeConstructor()
501 : StandardConstructorBase( I18N_NOOP( "Sides of a Polygon" ),
502 I18N_NOOP( "The sides of a polygon." ),
503 "polygonsides", margsparser
),
504 mtype( PolygonSideType::instance() ),
505 margsparser( argsspecps
, 1 )
509 PolygonSideTypeConstructor::~PolygonSideTypeConstructor()
513 void PolygonSideTypeConstructor::drawprelim( const ObjectDrawer
& drawer
, KigPainter
& p
, const std::vector
<ObjectCalcer
*>& parents
,
514 const KigDocument
& ) const
516 if ( parents
.size() != 1 ) return;
518 const PolygonImp
* polygon
= dynamic_cast<const PolygonImp
*>( parents
.front()->imp() );
519 const std::vector
<Coordinate
> points
= polygon
->points();
521 uint sides
= points
.size();
522 for ( uint i
= 0; i
< sides
; ++i
)
524 uint nexti
= ( i
+ 1 < sides
)?(i
+ 1):0;
525 SegmentImp segment
= SegmentImp( points
[i
], points
[nexti
] );
526 drawer
.draw( segment
, p
, true );
530 std::vector
<ObjectHolder
*> PolygonSideTypeConstructor::build( const std::vector
<ObjectCalcer
*>& parents
, KigDocument
&, KigWidget
& ) const
532 std::vector
<ObjectHolder
*> ret
;
533 assert( parents
.size() == 1 );
534 const PolygonImp
* polygon
= dynamic_cast<const PolygonImp
*>( parents
.front()->imp() );
535 const std::vector
<Coordinate
> points
= polygon
->points();
537 uint sides
= points
.size();
539 for ( uint i
= 0; i
< sides
; ++i
)
541 ObjectConstCalcer
* d
= new ObjectConstCalcer( new IntImp( i
) );
542 std::vector
<ObjectCalcer
*> args( parents
);
544 ret
.push_back( new ObjectHolder( new ObjectTypeCalcer( mtype
, args
) ) );
549 void PolygonSideTypeConstructor::plug( KigPart
*, KigGUIAction
* )
553 bool PolygonSideTypeConstructor::isTransform() const
559 * polygon by center and vertex
562 PolygonBCVConstructor::PolygonBCVConstructor()
563 : mtype( PolygonBCVType::instance() )
567 PolygonBCVConstructor::~PolygonBCVConstructor()
571 const QString
PolygonBCVConstructor::descriptiveName() const
573 return i18n("Regular Polygon with Given Center");
576 const QString
PolygonBCVConstructor::description() const
578 return i18n("Construct a regular polygon with a given center and vertex");
581 const QCString
PolygonBCVConstructor::iconFileName( const bool ) const
586 const bool PolygonBCVConstructor::isAlreadySelectedOK(
587 const std::vector
<ObjectCalcer
*>&, const int& ) const
592 const int PolygonBCVConstructor::wantArgs( const std::vector
<ObjectCalcer
*>& os
,
594 const KigWidget
& ) const
596 if ( os
.size() > 3 ) return ArgsParser::Invalid
;
598 uint imax
= ( os
.size() <= 2) ? os
.size() : 2;
599 for ( uint i
= 0; i
< imax
; ++i
)
600 if ( ! ( os
[i
]->imp()->inherits( PointImp::stype() ) ) ) return ArgsParser::Invalid
;
602 if ( os
.size() < 3 ) return ArgsParser::Valid
;
604 if ( ! ( os
[2]->imp()->inherits( BogusPointImp::stype() ) ) )
605 return ArgsParser::Invalid
;
607 return ArgsParser::Complete
;
610 void PolygonBCVConstructor::handleArgs(
611 const std::vector
<ObjectCalcer
*>& os
, KigPart
& d
,
614 std::vector
<ObjectHolder
*> bos
= build( os
, d
.document(), v
);
615 for ( std::vector
<ObjectHolder
*>::iterator i
= bos
.begin();
616 i
!= bos
.end(); ++i
)
618 (*i
)->calc( d
.document() );
624 void PolygonBCVConstructor::handlePrelim(
625 KigPainter
& p
, const std::vector
<ObjectCalcer
*>& os
,
626 const KigDocument
& d
, const KigWidget
&
629 if ( os
.size() < 2 ) return;
631 for ( uint i
= 0; i
< 2; i
++ )
633 assert ( os
[i
]->imp()->inherits( PointImp::stype() ) );
636 Coordinate c
= static_cast<const PointImp
*>( os
[0]->imp() )->coordinate();
637 Coordinate v
= static_cast<const PointImp
*>( os
[1]->imp() )->coordinate();
640 bool moreinfo
= false;
641 int winding
= 0; // 0 means allow winding > 1
642 if ( os
.size() == 3 )
644 assert ( os
[2]->imp()->inherits( BogusPointImp::stype() ) );
645 Coordinate cntrl
= static_cast<const PointImp
*>( os
[2]->imp() )->coordinate();
646 nsides
= computeNsides( c
, v
, cntrl
, winding
);
650 std::vector
<ObjectCalcer
*> args
;
651 args
.push_back( os
[0] );
652 args
.push_back( os
[1] );
653 ObjectConstCalcer
* ns
= new ObjectConstCalcer( new IntImp( nsides
) );
654 args
.push_back( ns
);
657 ns
= new ObjectConstCalcer( new IntImp( winding
) );
658 args
.push_back( ns
);
661 p
.setBrushStyle( Qt::NoBrush
);
662 p
.setBrushColor( Qt::red
);
663 p
.setPen( QPen ( Qt::red
, 1) );
664 p
.setWidth( -1 ); // -1 means the default width for the object being
667 ObjectDrawer
drawer( Qt::red
);
668 drawprelim( drawer
, p
, args
, d
);
671 p
.setPointStyle( 1 );
673 double ro
= 1.0/(2.5);
674 Coordinate where
= getRotatedCoord( c
, (1-ro
)*c
+ro
*v
, 4*M_PI
/5.0 );
675 PointImp ptn
= PointImp( where
);
676 TextImp text
= TextImp( "(5,2)", where
, false );
679 for ( int i
= 3; i
< 9; ++i
)
681 where
= getRotatedCoord( c
, v
, 2.0*M_PI
/i
);
682 ptn
= PointImp( where
);
684 if ( i
> 5 ) continue;
685 text
= TextImp( QString( "(%1)" ).arg(i
), where
, false );
688 p
.setStyle( Qt::DotLine
);
690 double radius
= ( v
- c
).length();
691 CircleImp circle
= CircleImp( c
, radius
);
693 for ( int i
= 2; i
< 5; i
++ )
696 CircleImp circle
= CircleImp( c
, ro
*radius
);
702 std::vector
<ObjectHolder
*> PolygonBCVConstructor::build( const std::vector
<ObjectCalcer
*>& parents
, KigDocument
&, KigWidget
& ) const
704 assert ( parents
.size() == 3 );
705 std::vector
<ObjectCalcer
*> args
;
707 Coordinate c
= static_cast<const PointImp
*>( parents
[0]->imp() )->coordinate();
708 Coordinate v
= static_cast<const PointImp
*>( parents
[1]->imp() )->coordinate();
709 Coordinate cntrl
= static_cast<const PointImp
*>( parents
[2]->imp() )->coordinate();
711 args
.push_back( parents
[0] );
712 args
.push_back( parents
[1] );
714 int nsides
= computeNsides( c
, v
, cntrl
, winding
);
715 ObjectConstCalcer
* d
= new ObjectConstCalcer( new IntImp( nsides
) );
719 d
= new ObjectConstCalcer( new IntImp( winding
) );
723 ObjectTypeCalcer
* calcer
= new ObjectTypeCalcer( mtype
, args
);
724 ObjectHolder
* h
= new ObjectHolder( calcer
);
725 std::vector
<ObjectHolder
*> ret
;
730 QString
PolygonBCVConstructor::useText( const ObjectCalcer
&, const std::vector
<ObjectCalcer
*>& os
,
731 const KigDocument
&, const KigWidget
& ) const
736 return i18n( "Construct a regular polygon with this center" );
740 return i18n( "Construct a regular polygon with this vertex" );
744 Coordinate c
= static_cast<const PointImp
*>( os
[0]->imp() )->coordinate();
745 Coordinate v
= static_cast<const PointImp
*>( os
[1]->imp() )->coordinate();
746 Coordinate cntrl
= static_cast<const PointImp
*>( os
[2]->imp() )->coordinate();
748 int nsides
= computeNsides( c
, v
, cntrl
, winding
);
752 QString result
= QString(
753 i18n( "Adjust the number of sides (%1/%2)" )
754 ).arg( nsides
).arg( winding
);
758 QString result
= QString(
759 i18n( "Adjust the number of sides (%1)" )
769 QString
PolygonBCVConstructor::selectStatement(
770 const std::vector
<ObjectCalcer
*>& os
, const KigDocument
&,
771 const KigWidget
& ) const
776 return i18n( "Select the center of the new polygon..." );
780 return i18n( "Select a vertex for the new polygon..." );
784 return i18n( "Move the cursor to get the desired number of sides..." );
791 void PolygonBCVConstructor::drawprelim( const ObjectDrawer
& drawer
, KigPainter
& p
, const std::vector
<ObjectCalcer
*>& parents
,
792 const KigDocument
& doc
) const
794 if ( parents
.size() < 3 || parents
.size() > 4 ) return;
796 assert ( parents
[0]->imp()->inherits( PointImp::stype() ) &&
797 parents
[1]->imp()->inherits( PointImp::stype() ) &&
798 parents
[2]->imp()->inherits( IntImp::stype() ) );
800 if ( parents
.size() == 4 )
801 assert ( parents
[3]->imp()->inherits( IntImp::stype() ) );
804 std::transform( parents
.begin(), parents
.end(),
805 std::back_inserter( args
), std::mem_fun( &ObjectCalcer::imp
) );
807 ObjectImp
* data
= mtype
->calc( args
, doc
);
808 drawer
.draw( *data
, p
, true );
813 void PolygonBCVConstructor::plug( KigPart
*, KigGUIAction
* )
817 bool PolygonBCVConstructor::isTransform() const
822 Coordinate
PolygonBCVConstructor::getRotatedCoord( const Coordinate
& c
,
823 const Coordinate
& v
, double alpha
) const
825 double cosalpha
= cos(alpha
);
826 double sinalpha
= sin(alpha
);
827 double dx
= v
.x
- c
.x
;
828 double dy
= v
.y
- c
.y
;
829 return c
+ Coordinate( cosalpha
*dx
- sinalpha
*dy
, sinalpha
*dx
+ cosalpha
*dy
);
832 int PolygonBCVConstructor::computeNsides ( const Coordinate
& c
,
833 const Coordinate
& v
, const Coordinate
& cntrl
, int& winding
) const
835 Coordinate lvect
= v
- c
;
836 Coordinate rvect
= cntrl
- c
;
838 double angle
= atan2( rvect
.y
, rvect
.x
) - atan2( lvect
.y
, lvect
.x
);
839 angle
= fabs( angle
/(2*M_PI
) );
840 while ( angle
> 1 ) angle
-= 1;
841 if ( angle
> 0.5 ) angle
= 1 - angle
;
843 double realsides
= 1.0/angle
; // this is bigger that 2
844 if ( angle
== 0. ) realsides
= 3;
845 if ( winding
<= 0 ) // free to compute winding
848 double ratio
= lvect
.length()/rvect
.length();
849 winding
= int ( ratio
);
850 if ( winding
< 1 ) winding
= 1;
851 if ( winding
> 50 ) winding
= 50;
853 int nsides
= int( winding
*realsides
+ 0.5 ); // nsides/winding should be reduced!
854 if ( nsides
> 100 ) nsides
= 100; // well, 100 seems large enough!
855 if ( nsides
< 3 ) nsides
= 3;
856 while ( !relativePrimes ( nsides
, winding
) ) ++nsides
;
861 * ConicConic intersection...
864 static const ArgsParser::spec argsspectc
[] = {
865 { ConicImp::stype(), "SHOULD NOT BE SEEN", "SHOULD NOT BE SEEN", true },
866 { ConicImp::stype(), "SHOULD NOT BE SEEN", "SHOULD NOT BE SEEN", true }
869 ConicConicIntersectionConstructor::ConicConicIntersectionConstructor()
870 : StandardConstructorBase( "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
871 "curvelineintersection", mparser
),
872 mparser( argsspectc
, 2 )
876 ConicConicIntersectionConstructor::~ConicConicIntersectionConstructor()
880 void ConicConicIntersectionConstructor::drawprelim( const ObjectDrawer
& drawer
, KigPainter
& p
, const std::vector
<ObjectCalcer
*>& parents
,
881 const KigDocument
& ) const
883 if ( parents
.size() != 2 ) return;
884 assert ( parents
[0]->imp()->inherits( ConicImp::stype() ) &&
885 parents
[1]->imp()->inherits( ConicImp::stype() ) );
886 const ConicCartesianData conica
=
887 static_cast<const ConicImp
*>( parents
[0]->imp() )->cartesianData();
888 const ConicCartesianData conicb
=
889 static_cast<const ConicImp
*>( parents
[1]->imp() )->cartesianData();
891 for ( int wr
= -1; wr
< 2; wr
+= 2 )
893 LineData radical
= calcConicRadical( conica
, conicb
, wr
, 1, ok
);
896 for ( int wi
= -1; wi
< 2; wi
+= 2 )
898 Coordinate c
= calcConicLineIntersect( conica
, radical
, 0.0, wi
);
901 drawer
.draw( pi
, p
, true );
908 std::vector
<ObjectHolder
*> ConicConicIntersectionConstructor::build(
909 const std::vector
<ObjectCalcer
*>& os
, KigDocument
& doc
, KigWidget
& ) const
911 assert( os
.size() == 2 );
912 std::vector
<ObjectHolder
*> ret
;
913 ObjectCalcer
* conica
= os
[0];
914 ObjectConstCalcer
* zeroindexdo
= new ObjectConstCalcer( new IntImp( 1 ) );
916 for ( int wr
= -1; wr
< 2; wr
+= 2 )
918 std::vector
<ObjectCalcer
*> args
= os
;
919 args
.push_back( new ObjectConstCalcer( new IntImp( wr
) ) );
920 args
.push_back( zeroindexdo
);
921 ObjectTypeCalcer
* radical
=
922 new ObjectTypeCalcer( ConicRadicalType::instance(), args
);
923 radical
->calc( doc
);
924 for ( int wi
= -1; wi
< 2; wi
+= 2 )
927 args
.push_back( conica
);
928 args
.push_back( radical
);
929 args
.push_back( new ObjectConstCalcer( new IntImp( wi
) ) );
932 new ObjectTypeCalcer(
933 ConicLineIntersectionType::instance(), args
) ) );
939 void ConicConicIntersectionConstructor::plug( KigPart
*, KigGUIAction
* )
943 bool ConicConicIntersectionConstructor::isTransform() const
948 ConicLineIntersectionConstructor::ConicLineIntersectionConstructor()
949 : MultiObjectTypeConstructor(
950 ConicLineIntersectionType::instance(),
951 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
952 "curvelineintersection", -1, 1 )
956 ConicLineIntersectionConstructor::~ConicLineIntersectionConstructor()
960 ArcLineIntersectionConstructor::ArcLineIntersectionConstructor()
961 : MultiObjectTypeConstructor(
962 ArcLineIntersectionType::instance(),
963 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
964 "curvelineintersection", -1, 1 )
968 ArcLineIntersectionConstructor::~ArcLineIntersectionConstructor()
972 QString
ConicRadicalConstructor::useText( const ObjectCalcer
& o
, const std::vector
<ObjectCalcer
*>&,
973 const KigDocument
&, const KigWidget
& ) const
975 if ( o
.imp()->inherits( CircleImp::stype() ) )
976 return i18n( "Construct the Radical Lines of This Circle" );
978 return i18n( "Construct the Radical Lines of This Conic" );
982 * generic affinity and generic projectivity. A unique affinity can be
983 * obtained by specifying the image of three points (four for projectivity)
984 * in the end we need, besides the object to be transformed, a total of
985 * six point or (alternatively) two triangles; our affinity will map the
986 * first triangle onto the second with corresponding ordering of their
987 * vertices. Since we allow for two different ways of specifying the six
988 * points we shall use a Generic constructor, like that for intersections.
991 GenericAffinityConstructor::GenericAffinityConstructor()
992 : MergeObjectConstructor(
993 I18N_NOOP( "Generic Affinity" ),
994 I18N_NOOP( "The unique affinity that maps three points (or a triangle) onto three other points (or a triangle)" ),
997 SimpleObjectTypeConstructor
* b2tr
=
998 new SimpleObjectTypeConstructor(
999 AffinityB2TrType::instance(),
1000 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1001 "genericaffinity" );
1003 SimpleObjectTypeConstructor
* gi3p
=
1004 new SimpleObjectTypeConstructor(
1005 AffinityGI3PType::instance(),
1006 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1007 "genericaffinity" );
1013 GenericAffinityConstructor::~GenericAffinityConstructor() {}
1015 GenericProjectivityConstructor::GenericProjectivityConstructor()
1016 : MergeObjectConstructor(
1017 I18N_NOOP( "Generic Projective Transformation" ),
1018 I18N_NOOP( "The unique projective transformation that maps four points (or a quadrilateral) onto four other points (or a quadrilateral)" ),
1019 "genericprojectivity" )
1021 SimpleObjectTypeConstructor
* b2qu
=
1022 new SimpleObjectTypeConstructor(
1023 ProjectivityB2QuType::instance(),
1024 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1025 "genericprojectivity" );
1027 SimpleObjectTypeConstructor
* gi4p
=
1028 new SimpleObjectTypeConstructor(
1029 ProjectivityGI4PType::instance(),
1030 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1031 "genericprojectivity" );
1037 GenericProjectivityConstructor::~GenericProjectivityConstructor() {}
1040 * inversion of points, lines with respect to a circle
1043 InversionConstructor::InversionConstructor()
1044 : MergeObjectConstructor(
1045 I18N_NOOP( "Inversion of Point, Line or Circle" ),
1046 I18N_NOOP( "The inversion of a point, line or circle with respect to a circle" ),
1049 SimpleObjectTypeConstructor
* pointobj
=
1050 new SimpleObjectTypeConstructor(
1051 InvertPointType::instance(),
1052 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1055 SimpleObjectTypeConstructor
* lineobj
=
1056 new SimpleObjectTypeConstructor(
1057 InvertLineType::instance(),
1058 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1061 SimpleObjectTypeConstructor
* circleobj
=
1062 new SimpleObjectTypeConstructor(
1063 InvertCircleType::instance(),
1064 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1072 InversionConstructor::~InversionConstructor() {}
1075 * Transport of Measure
1078 MeasureTransportConstructor::MeasureTransportConstructor()
1079 : mtype( MeasureTransportType::instance() )
1083 MeasureTransportConstructor::~MeasureTransportConstructor()
1087 const QString
MeasureTransportConstructor::descriptiveName() const
1089 return i18n("Measure Transport");
1092 const QString
MeasureTransportConstructor::description() const
1094 return i18n("Transport the measure of a segment or arc over a line or circle.");
1097 const QCString
MeasureTransportConstructor::iconFileName( const bool ) const
1099 return "measuretransport";
1102 const bool MeasureTransportConstructor::isAlreadySelectedOK(
1103 const std::vector
<ObjectCalcer
*>&, const int& ) const
1109 * we want the arguments in the exact order, this makes
1110 * the code simpler, but I guess it is also less confusing
1114 const int MeasureTransportConstructor::wantArgs(
1115 const std::vector
<ObjectCalcer
*>& os
,
1117 const KigWidget
& ) const
1119 if ( os
.size() == 0 ) return ArgsParser::Valid
;
1121 if ( ! os
[0]->imp()->inherits( SegmentImp::stype() ) &&
1122 ! os
[0]->imp()->inherits( ArcImp::stype() ) )
1123 return ArgsParser::Invalid
;
1125 if ( os
.size() == 1 ) return ArgsParser::Valid
;
1127 if ( ! os
[1]->imp()->inherits( LineImp::stype() ) &&
1128 ! os
[1]->imp()->inherits( CircleImp::stype() ) )
1129 return ArgsParser::Invalid
;
1131 if ( os
.size() == 2 ) return ArgsParser::Valid
;
1133 if ( ! os
[2]->imp()->inherits( PointImp::stype() ) )
1134 return ArgsParser::Invalid
;
1136 // we here use the "isPointOnCurve", which relies on
1137 // "by construction" incidence, instead of a numerical
1139 if ( ! isPointOnCurve( os
[2], os
[1] ) )
1140 return ArgsParser::Invalid
;
1142 if ( os
.size() == 3 ) return ArgsParser::Complete
;
1144 return ArgsParser::Invalid
;
1147 void MeasureTransportConstructor::handleArgs(
1148 const std::vector
<ObjectCalcer
*>& os
, KigPart
& d
,
1149 KigWidget
& v
) const
1151 std::vector
<ObjectHolder
*> bos
= build( os
, d
.document(), v
);
1152 for ( std::vector
<ObjectHolder
*>::iterator i
= bos
.begin();
1153 i
!= bos
.end(); ++i
)
1155 (*i
)->calc( d
.document() );
1158 d
.addObjects( bos
);
1161 void MeasureTransportConstructor::handlePrelim(
1162 KigPainter
& p
, const std::vector
<ObjectCalcer
*>& os
,
1163 const KigDocument
& d
, const KigWidget
&
1166 p
.setBrushStyle( Qt::NoBrush
);
1167 p
.setBrushColor( Qt::red
);
1168 p
.setPen( QPen ( Qt::red
, 1) );
1169 p
.setWidth( -1 ); // -1 means the default width for the object being
1172 ObjectDrawer
drawer( Qt::red
);
1173 drawprelim( drawer
, p
, os
, d
);
1176 void MeasureTransportConstructor::drawprelim( const ObjectDrawer
& drawer
,
1178 const std::vector
<ObjectCalcer
*>& parents
,
1179 const KigDocument
& doc
) const
1182 using namespace std
;
1183 transform( parents
.begin(), parents
.end(),
1184 back_inserter( args
), mem_fun( &ObjectCalcer::imp
) );
1185 ObjectImp
* data
= mtype
->calc( args
, doc
);
1186 drawer
.draw( *data
, p
, true );
1190 QString
MeasureTransportConstructor::useText( const ObjectCalcer
& o
,
1191 const std::vector
<ObjectCalcer
*>& os
,
1192 const KigDocument
&, const KigWidget
& ) const
1194 if ( o
.imp()->inherits( SegmentImp::stype() ) )
1195 return i18n("Segment to transport");
1196 if ( o
.imp()->inherits( ArcImp::stype() ) )
1197 return i18n("Arc to transport");
1198 if ( o
.imp()->inherits( LineImp::stype() ) )
1199 return i18n("Transport a measure on this line");
1200 if ( o
.imp()->inherits( CircleImp::stype() ) )
1201 return i18n("Transport a measure on this circle");
1202 if ( o
.imp()->inherits( PointImp::stype() ) )
1204 if ( os
[1]->imp()->inherits( CircleImp::stype() ) )
1205 return i18n("Start transport from this point of the circle");
1206 if ( os
[1]->imp()->inherits( LineImp::stype() ) )
1207 return i18n("Start transport from this point of the line");
1209 return i18n("Start transport from this point of the curve");
1210 // well, this isn't impemented yet, should never get here
1215 QString
MeasureTransportConstructor::selectStatement(
1216 const std::vector
<ObjectCalcer
*>&, const KigDocument
&,
1217 const KigWidget
& ) const
1220 return i18n("Select a point to be a vertex of the new polygon...");
1223 std::vector
<ObjectHolder
*> MeasureTransportConstructor::build(
1224 const std::vector
<ObjectCalcer
*>& parents
,
1225 KigDocument
&, KigWidget
& ) const
1227 assert ( parents
.size() == 3 );
1228 // std::vector<ObjectCalcer*> args;
1229 // for ( uint i = 0; i < count; ++i ) args.push_back( parents[i] );
1230 ObjectTypeCalcer
* calcer
= new ObjectTypeCalcer( mtype
, parents
);
1231 ObjectHolder
* h
= new ObjectHolder( calcer
);
1232 std::vector
<ObjectHolder
*> ret
;
1237 void MeasureTransportConstructor::plug( KigPart
*, KigGUIAction
* )
1241 bool MeasureTransportConstructor::isTransform() const
1247 * Generic intersection
1250 GenericIntersectionConstructor::GenericIntersectionConstructor()
1251 : MergeObjectConstructor(
1252 I18N_NOOP( "Intersect" ),
1253 I18N_NOOP( "The intersection of two objects" ),
1254 "curvelineintersection" )
1256 // intersection type..
1257 // There is one "toplevel" object_constructor, that is composed
1258 // of multiple subconstructors.. First we build the
1260 SimpleObjectTypeConstructor
* lineline
=
1261 new SimpleObjectTypeConstructor(
1262 LineLineIntersectionType::instance(),
1263 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1264 "curvelineintersection" );
1266 ObjectConstructor
* lineconic
=
1267 new ConicLineIntersectionConstructor();
1269 ObjectConstructor
* arcline
=
1270 new ArcLineIntersectionConstructor();
1272 MultiObjectTypeConstructor
* linecubic
=
1273 new MultiObjectTypeConstructor(
1274 LineCubicIntersectionType::instance(),
1275 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1276 "curvelineintersection", 1, 2, 3 );
1278 ObjectConstructor
* conicconic
=
1279 new ConicConicIntersectionConstructor();
1281 MultiObjectTypeConstructor
* circlecircle
=
1282 new MultiObjectTypeConstructor(
1283 CircleCircleIntersectionType::instance(),
1284 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1285 "circlecircleintersection", -1, 1 );
1287 SimpleObjectTypeConstructor
* polygonline
=
1288 new SimpleObjectTypeConstructor(
1289 PolygonLineIntersectionType::instance(),
1290 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1291 "curvelineintersection" );
1294 merge( circlecircle
);
1297 merge( conicconic
);
1299 merge( polygonline
);
1302 GenericIntersectionConstructor::~GenericIntersectionConstructor()
1306 bool GenericIntersectionConstructor::isIntersection() const
1311 QString
GenericIntersectionConstructor::useText(
1312 const ObjectCalcer
& o
, const std::vector
<ObjectCalcer
*>& os
,
1313 const KigDocument
&, const KigWidget
& ) const
1319 if ( o
.imp()->inherits( CircleImp::stype() ) )
1320 return i18n( "Intersect this Circle" );
1321 else if ( o
.imp()->inherits( ConicImp::stype() ) )
1322 return i18n( "Intersect this Conic" );
1323 else if ( o
.imp()->inherits( AbstractLineImp::stype() ) )
1324 return i18n( "Intersect this Line" );
1325 else if ( o
.imp()->inherits( CubicImp::stype() ) )
1326 return i18n( "Intersect this Cubic Curve" );
1327 else if ( o
.imp()->inherits( ArcImp::stype() ) )
1328 return i18n( "Intersect this Arc" );
1329 else if ( o
.imp()->inherits( PolygonImp::stype() ) )
1330 return i18n( "Intersect this Polygon" );
1331 else assert( false );
1334 if ( o
.imp()->inherits( CircleImp::stype() ) )
1335 return i18n( "with this Circle" );
1336 else if ( o
.imp()->inherits( ConicImp::stype() ) )
1337 return i18n( "with this Conic" );
1338 else if ( o
.imp()->inherits( AbstractLineImp::stype() ) )
1339 return i18n( "with this Line" );
1340 else if ( o
.imp()->inherits( CubicImp::stype() ) )
1341 return i18n( "with this Cubic Curve" );
1342 else if ( o
.imp()->inherits( ArcImp::stype() ) )
1343 return i18n( "with this Arc" );
1344 else if ( o
.imp()->inherits( PolygonImp::stype() ) )
1345 return i18n( "with this Polygon" );
1346 else assert( false );
1350 return QString::null
;
1353 static const ArgsParser::spec argsspecMidPointOfTwoPoints
[] =
1355 { PointImp::stype(), I18N_NOOP( "Construct Midpoint of This Point and Another One" ),
1356 I18N_NOOP( "Select the first of the points of which you want to construct the midpoint..." ), false },
1357 { PointImp::stype(), I18N_NOOP( "Construct the midpoint of this point and another one" ),
1358 I18N_NOOP( "Select the other of the points of which to construct the midpoint..." ), false }
1361 MidPointOfTwoPointsConstructor::MidPointOfTwoPointsConstructor()
1362 : StandardConstructorBase( "Mid Point",
1363 "Construct the midpoint of two points",
1364 "bisection", mparser
),
1365 mparser( argsspecMidPointOfTwoPoints
, 2 )
1369 MidPointOfTwoPointsConstructor::~MidPointOfTwoPointsConstructor()
1373 void MidPointOfTwoPointsConstructor::drawprelim(
1374 const ObjectDrawer
& drawer
, KigPainter
& p
, const std::vector
<ObjectCalcer
*>& parents
,
1375 const KigDocument
& ) const
1377 if ( parents
.size() != 2 ) return;
1378 assert( parents
[0]->imp()->inherits( PointImp::stype() ) );
1379 assert( parents
[1]->imp()->inherits( PointImp::stype() ) );
1380 const Coordinate m
=
1381 ( static_cast<const PointImp
*>( parents
[0]->imp() )->coordinate() +
1382 static_cast<const PointImp
*>( parents
[1]->imp() )->coordinate() ) / 2;
1383 drawer
.draw( PointImp( m
), p
, true );
1386 std::vector
<ObjectHolder
*> MidPointOfTwoPointsConstructor::build(
1387 const std::vector
<ObjectCalcer
*>& os
, KigDocument
& d
, KigWidget
& ) const
1389 ObjectTypeCalcer
* seg
= new ObjectTypeCalcer( SegmentABType::instance(), os
);
1391 int index
= seg
->imp()->propertiesInternalNames().findIndex( "mid-point" );
1392 assert( index
!= -1 );
1393 ObjectPropertyCalcer
* prop
= new ObjectPropertyCalcer( seg
, index
);
1395 std::vector
<ObjectHolder
*> ret
;
1396 ret
.push_back( new ObjectHolder( prop
) );
1400 void MidPointOfTwoPointsConstructor::plug( KigPart
*, KigGUIAction
* )
1404 bool MidPointOfTwoPointsConstructor::isTransform() const
1409 TestConstructor::TestConstructor( const ArgsParserObjectType
* type
, const char* descname
,
1410 const char* desc
, const char* iconfile
)
1411 : StandardConstructorBase( descname
, desc
, iconfile
, type
->argsParser() ),
1416 TestConstructor::~TestConstructor()
1420 void TestConstructor::drawprelim( const ObjectDrawer
&, KigPainter
&, const std::vector
<ObjectCalcer
*>&,
1421 const KigDocument
& ) const
1423 // not used, only here because of the wrong
1424 // ObjectConstructor-GUIAction design. See the TODO
1427 std::vector
<ObjectHolder
*> TestConstructor::build( const std::vector
<ObjectCalcer
*>&, KigDocument
&,
1430 // not used, only here because of the wrong
1431 // ObjectConstructor-GUIAction design. See the TODO
1432 std::vector
<ObjectHolder
*> ret
;
1436 void TestConstructor::plug( KigPart
*, KigGUIAction
* )
1440 bool TestConstructor::isTransform() const
1445 bool TestConstructor::isTest() const
1450 BaseConstructMode
* TestConstructor::constructMode( KigPart
& doc
)
1452 return new TestConstructMode( doc
, mtype
);
1455 const int TestConstructor::wantArgs( const std::vector
<ObjectCalcer
*>& os
,
1456 const KigDocument
& d
, const KigWidget
& v
) const
1458 int ret
= StandardConstructorBase::wantArgs( os
, d
, v
);
1459 if ( ret
== ArgsParser::Complete
) ret
= ArgsParser::Valid
;
1463 QString
GenericIntersectionConstructor::selectStatement(
1464 const std::vector
<ObjectCalcer
*>& sel
, const KigDocument
&,
1465 const KigWidget
& ) const
1467 if ( sel
.size() == 0 )
1468 return i18n( "Select the first object to intersect..." );
1470 return i18n( "Select the second object to intersect..." );
1473 TangentConstructor::TangentConstructor()
1474 : MergeObjectConstructor(
1475 I18N_NOOP( "Tangent" ),
1476 I18N_NOOP( "The line tangent to a curve" ),
1479 SimpleObjectTypeConstructor
* conic
=
1480 new SimpleObjectTypeConstructor(
1481 TangentConicType::instance(),
1482 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1485 SimpleObjectTypeConstructor
* arc
=
1486 new SimpleObjectTypeConstructor(
1487 TangentArcType::instance(),
1488 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1491 SimpleObjectTypeConstructor
* cubic
=
1492 new SimpleObjectTypeConstructor(
1493 TangentCubicType::instance(),
1494 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1497 SimpleObjectTypeConstructor
* curve
=
1498 new SimpleObjectTypeConstructor(
1499 TangentCurveType::instance(),
1500 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1509 TangentConstructor::~TangentConstructor()
1513 QString
TangentConstructor::useText(
1514 const ObjectCalcer
& o
, const std::vector
<ObjectCalcer
*>&,
1515 const KigDocument
&, const KigWidget
& ) const
1517 if ( o
.imp()->inherits( CircleImp::stype() ) )
1518 return i18n( "Tangent to This Circle" );
1519 else if ( o
.imp()->inherits( ConicImp::stype() ) )
1520 return i18n( "Tangent to This Conic" );
1521 else if ( o
.imp()->inherits( ArcImp::stype() ) )
1522 return i18n( "Tangent to This Arc" );
1523 else if ( o
.imp()->inherits( CubicImp::stype() ) )
1524 return i18n( "Tangent to This Cubic Curve" );
1525 else if ( o
.imp()->inherits( CurveImp::stype() ) )
1526 return i18n( "Tangent to This Curve" );
1527 else if ( o
.imp()->inherits( PointImp::stype() ) )
1528 return i18n( "Tangent at This Point" );
1529 // else assert( false );
1530 return QString::null
;
1533 //QString TangentConstructor::selectStatement(
1534 // const std::vector<ObjectCalcer*>& sel, const KigDocument&,
1535 // const KigWidget& ) const
1537 // if ( sel.size() == 0 )
1538 // return i18n( "Select the object..." );
1540 // return i18n( "Select the point for the tangent to go through..." );
1544 * center of curvature of a curve
1547 CocConstructor::CocConstructor()
1548 : MergeObjectConstructor(
1549 I18N_NOOP( "Center Of Curvature" ),
1550 I18N_NOOP( "The center of the osculating circle to a curve" ),
1551 "centerofcurvature" )
1553 SimpleObjectTypeConstructor
* conic
=
1554 new SimpleObjectTypeConstructor(
1555 CocConicType::instance(),
1556 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1559 SimpleObjectTypeConstructor
* cubic
=
1560 new SimpleObjectTypeConstructor(
1561 CocCubicType::instance(),
1562 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1565 SimpleObjectTypeConstructor
* curve
=
1566 new SimpleObjectTypeConstructor(
1567 CocCurveType::instance(),
1568 "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
1576 CocConstructor::~CocConstructor()
1580 QString
CocConstructor::useText(
1581 const ObjectCalcer
& o
, const std::vector
<ObjectCalcer
*>&,
1582 const KigDocument
&, const KigWidget
& ) const
1584 if ( o
.imp()->inherits( ConicImp::stype() ) )
1585 return i18n( "Center of Curvature of This Conic" );
1586 else if ( o
.imp()->inherits( CubicImp::stype() ) )
1587 return i18n( "Center of Curvature of This Cubic Curve" );
1588 else if ( o
.imp()->inherits( CurveImp::stype() ) )
1589 return i18n( "Center of Curvature of This Curve" );
1590 else if ( o
.imp()->inherits( PointImp::stype() ) )
1591 return i18n( "Center of Curvature at This Point" );
1592 return QString::null
;
1595 bool relativePrimes( int n
, int p
)
1597 if ( p
> n
) return relativePrimes( p
, n
);
1599 if ( p
== 0 ) return false;
1600 if ( p
== 1 ) return true;
1602 return relativePrimes( p
, n
-d
*p
);
1605 //QString CocConstructor::selectStatement(
1606 // const std::vector<ObjectCalcer*>& sel, const KigDocument&,
1607 // const KigWidget& ) const
1609 // if ( sel.size() == 0 )
1610 // return i18n( "Select the object..." );
1612 // return i18n( "Select the point where to compute the center of curvature..." );