23#include <tqvaluelist.h>
27#include "vbooleancmd.h"
30#include "vselection.h"
33VBooleanCmd::VBooleanCmd(
VDocument *doc, VBooleanType type )
34 :
VCommand( doc, i18n(
"Boolean Operation" ) )
36 m_selection = document()->selection()->clone();
40VBooleanCmd::~VBooleanCmd()
42 delete( m_selection );
48 VObjectListIterator itr( m_selection->objects() );
49 for ( ; itr.current() ; ++itr )
75VBooleanCmd::visitVSubpath(
VSubpath& path )
79 else if( m_path2 == 0L )
86 VParamList::iterator pItr;
93 while( m_path1->next() )
100 while( m_path2->next() )
104 recursiveSubdivision(
105 *m_path1->current(), 0.0, 1.0,
106 *m_path2->current(), 0.0, 1.0,
109 qHeapSort( params2 );
114 for( pItr = params2.begin(); pItr != params2.end(); ++pItr )
117 m_path2->current()->splitAt(
118 ( *pItr - prevParam )/( 1.0 - prevParam ) ) );
125 qHeapSort( params1 );
130 for( pItr = params1.begin(); pItr != params1.end(); ++pItr )
133 m_path1->current()->splitAt(
134 ( *pItr - prevParam )/( 1.0 - prevParam ) ) );
144VBooleanCmd::recursiveSubdivision(
145 const VSegment& segment1,
double t0_1,
double t1_1,
146 const VSegment& segment2,
double t0_2,
double t1_2,
147 VParamList& params1, VParamList& params2 )
164 double det = v2.x() * v1.y() - v2.y() * v1.x();
166 if( 1.0 + det == 1.0 )
171 const double one_det = 1.0 / det;
173 double t1 = one_det * ( v2.x() * v.y() - v2.y() * v.x() );
174 double t2 = one_det * ( v1.x() * v.y() - v1.y() * v.x() );
176 if ( t1 < 0.0 || t1 > 1.0 || t2 < 0.0 || t2 > 1.0 )
179 params1.append( t0_1 + t1 * ( t1_1 - t0_1 ) );
180 params2.append( t0_2 + t2 * ( t1_2 - t0_2 ) );
186 VSubpath path2( segment2 );
187 path2.insert( path2.current()->splitAt( 0.5 ) );
189 double mid2 = 0.5 * ( t0_2 + t1_2 );
191 recursiveSubdivision(
192 *path2.current(), t0_2, mid2,
193 segment1, t0_1, t1_1, params2, params1 );
194 recursiveSubdivision(
195 *path2.next(), mid2, t1_2,
196 segment1, t0_1, t1_1, params2, params1 );
202 VSubpath path1( segment1 );
203 path1.insert( path1.current()->splitAt( 0.5 ) );
205 double mid1 = 0.5 * ( t0_1 + t1_1 );
209 recursiveSubdivision(
210 *path1.current(), t0_1, mid1,
211 segment2, t0_2, t1_2, params1, params2 );
212 recursiveSubdivision(
213 *path1.next(), mid1, t1_1,
214 segment2, t0_2, t1_2, params1, params2 );
219 VSubpath path2( segment2 );
220 path2.insert( path2.current()->splitAt( 0.5 ) );
222 double mid2 = 0.5 * ( t0_2 + t1_2 );
224 recursiveSubdivision(
225 *path1.current(), t0_1, mid1,
226 *path2.current(), t0_2, mid2, params1, params2 );
227 recursiveSubdivision(
228 *path1.next(), mid1, t1_1,
229 *path2.current(), t0_2, mid2, params1, params2 );
231 recursiveSubdivision(
232 *path1.prev(), t0_1, mid1,
233 *path2.next(), mid2, t1_2, params1, params2 );
234 recursiveSubdivision(
235 *path1.next(), mid1, t1_1,
236 *path2.current(), mid2, t1_2, params1, params2 );
The base class for all karbon commands.
virtual void unexecute()
Unexecutes the command.
VDocument * document() const
Returns the document the command works on.
virtual void execute()=0
Executes the command.
All non-visual, static doc info is in here.
VSelection * selection() const
Returns a pointer to the selection.
The base class for all karbon objects.
virtual void accept(VVisitor &)
Accept a VVisitor.
A class representing lines and beziers.
bool isFlat(double flatness=VGlobal::flatnessTolerance) const
Returns true if the segment is flat.
VSegment * prev() const
Returns a pointer to the previous not deleted segment, if stored in a VSubpath.
const KoPoint & knot() const
Returns the knot.
KoRect boundingBox() const
Calculates the bounding box.
void clear()
Removes the references to all objects, not the objects themselves.
VSubpath provides a sophisticated list of VSegment.
bool success() const
Return if the operation was a success or not.