~ubuntu-branches/ubuntu/oneiric/kig/oneiric

« back to all changes in this revision

Viewing changes to objects/transform_types.cc

  • Committer: Bazaar Package Importer
  • Author(s): Harald Sitter
  • Date: 2011-07-10 11:57:38 UTC
  • Revision ID: james.westby@ubuntu.com-20110710115738-gdjnn1kctr49lmy9
Tags: upstream-4.6.90+repack
ImportĀ upstreamĀ versionĀ 4.6.90+repack

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (C)  2003  Dominique Devriese <devriese@kde.org>
 
2
 
 
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.
 
7
 
 
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.
 
12
 
 
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., 51 Franklin Street, Fifth Floor, Boston, MA
 
16
// 02110-1301, USA.
 
17
 
 
18
#include "transform_types.h"
 
19
 
 
20
#include <math.h>
 
21
 
 
22
#include "bogus_imp.h"
 
23
#include "point_imp.h"
 
24
#include "line_imp.h"
 
25
#include "other_imp.h"
 
26
#include "polygon_imp.h"
 
27
#include "special_imptypes.h"
 
28
#include "../misc/coordinate.h"
 
29
#include "../misc/kigtransform.h"
 
30
 
 
31
#include <cmath>
 
32
 
 
33
static const ArgsParser::spec argsspecTranslation[] =
 
34
{
 
35
  { ObjectImp::stype(), I18N_NOOP("Translate this object"),
 
36
    I18N_NOOP( "Select the object to translate..." ), false },
 
37
  { VectorImp::stype(), I18N_NOOP("Translate by this vector"),
 
38
    I18N_NOOP( "Select the vector to translate by..." ), false }
 
39
};
 
40
 
 
41
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( TranslatedType )
 
42
 
 
43
TranslatedType::TranslatedType()
 
44
  : ArgsParserObjectType( "Translation", argsspecTranslation, 2 )
 
45
{
 
46
}
 
47
 
 
48
TranslatedType::~TranslatedType()
 
49
{
 
50
}
 
51
 
 
52
const TranslatedType* TranslatedType::instance()
 
53
{
 
54
  static const TranslatedType t;
 
55
  return &t;
 
56
}
 
57
 
 
58
ObjectImp* TranslatedType::calc( const Args& args, const KigDocument& ) const
 
59
{
 
60
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
61
 
 
62
  Coordinate dir = static_cast<const VectorImp*>( args[1] )->dir();
 
63
  Transformation t = Transformation::translation( dir );
 
64
 
 
65
  return args[0]->transform( t );
 
66
}
 
67
 
 
68
static const ArgsParser::spec argsspecPointReflection[] =
 
69
{
 
70
  { ObjectImp::stype(), I18N_NOOP( "Reflect this object" ),
 
71
    I18N_NOOP( "Select the object to reflect..." ), false },
 
72
  { PointImp::stype(), I18N_NOOP( "Reflect in this point" ),
 
73
    I18N_NOOP( "Select the point to reflect in..." ), false }
 
74
};
 
75
 
 
76
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( PointReflectionType )
 
77
 
 
78
PointReflectionType::PointReflectionType()
 
79
  : ArgsParserObjectType( "PointReflection", argsspecPointReflection, 2 )
 
80
{
 
81
}
 
82
 
 
83
PointReflectionType::~PointReflectionType()
 
84
{
 
85
}
 
86
 
 
87
const PointReflectionType* PointReflectionType::instance()
 
88
{
 
89
  static const PointReflectionType t;
 
90
  return &t;
 
91
}
 
92
 
 
93
ObjectImp* PointReflectionType::calc( const Args& args, const KigDocument& ) const
 
94
{
 
95
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
96
 
 
97
  Coordinate center = static_cast<const PointImp*>( args[1] )->coordinate();
 
98
  Transformation t = Transformation::pointReflection( center );
 
99
 
 
100
  return args[0]->transform( t );
 
101
}
 
102
 
 
103
static const ArgsParser::spec argsspecLineReflection[] =
 
104
{
 
105
  { ObjectImp::stype(), I18N_NOOP( "Reflect this object" ),
 
106
    I18N_NOOP( "Select the object to reflect..." ), false },
 
107
  { AbstractLineImp::stype(), I18N_NOOP( "Reflect in this line" ),
 
108
    I18N_NOOP( "Select the line to reflect in..." ), false }
 
109
};
 
110
 
 
111
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( LineReflectionType )
 
112
 
 
113
LineReflectionType::LineReflectionType()
 
114
  : ArgsParserObjectType( "LineReflection", argsspecLineReflection, 2 )
 
115
{
 
116
}
 
117
 
 
118
LineReflectionType::~LineReflectionType()
 
119
{
 
120
}
 
121
 
 
122
const LineReflectionType* LineReflectionType::instance()
 
123
{
 
124
  static const LineReflectionType t;
 
125
  return &t;
 
126
}
 
127
 
 
128
ObjectImp* LineReflectionType::calc( const Args& args, const KigDocument& ) const
 
129
{
 
130
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
131
 
 
132
  LineData d = static_cast<const AbstractLineImp*>( args[1] )->data();
 
133
  Transformation t = Transformation::lineReflection( d );
 
134
 
 
135
  return args[0]->transform( t );
 
136
}
 
137
 
 
138
static const ArgsParser::spec argsspecRotation[] =
 
139
{
 
140
  { ObjectImp::stype(), I18N_NOOP( "Rotate this object" ),
 
141
    I18N_NOOP( "Select the object to rotate..." ), false },
 
142
  { PointImp::stype(), I18N_NOOP( "Rotate around this point" ),
 
143
    I18N_NOOP( "Select the center point of the rotation..." ), false },
 
144
//  { AngleImp::stype(), I18N_NOOP( "Rotate by this angle" ),
 
145
//    I18N_NOOP( "Select the angle of the rotation..." ), false }
 
146
  { &angleimptypeinstance, I18N_NOOP( "Rotate by this angle" ),
 
147
    I18N_NOOP( "Select the angle of the rotation..." ), false }
 
148
};
 
149
 
 
150
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( RotationType )
 
151
 
 
152
RotationType::RotationType()
 
153
  : ArgsParserObjectType( "Rotation", argsspecRotation, 3 )
 
154
{
 
155
}
 
156
 
 
157
RotationType::~RotationType()
 
158
{
 
159
}
 
160
 
 
161
const RotationType* RotationType::instance()
 
162
{
 
163
  static const RotationType t;
 
164
  return &t;
 
165
}
 
166
 
 
167
ObjectImp* RotationType::calc( const Args& args, const KigDocument& ) const
 
168
{
 
169
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
170
 
 
171
  Coordinate center = static_cast<const PointImp*>( args[1] )->coordinate();
 
172
//  double angle = static_cast<const AngleImp*>( args[2] )->size();
 
173
  bool valid;
 
174
  double angle = getDoubleFromImp( args[2], valid);
 
175
  if ( ! valid ) return new InvalidImp;
 
176
 
 
177
  return args[0]->transform( Transformation::rotation( angle, center ) );
 
178
}
 
179
 
 
180
static const ArgsParser::spec argsspecScalingOverCenter[] =
 
181
{
 
182
  { ObjectImp::stype(), I18N_NOOP( "Scale this object" ),
 
183
    I18N_NOOP( "Select the object to scale..." ), false },
 
184
  { PointImp::stype(), I18N_NOOP( "Scale with this center" ),
 
185
    I18N_NOOP( "Select the center point of the scaling..." ), false },
 
186
//  { SegmentImp::stype(), I18N_NOOP( "Scale by the length of this segment" ),
 
187
//    I18N_NOOP( "Select a segment whose length is the factor of the scaling..." ), false }
 
188
  { &lengthimptypeinstance, I18N_NOOP( "Scale by this length" ),
 
189
    I18N_NOOP( "Select a length or a segment whose length is the factor of the scaling..." ), false }
 
190
};
 
191
 
 
192
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ScalingOverCenterType )
 
193
 
 
194
ScalingOverCenterType::ScalingOverCenterType()
 
195
  : ArgsParserObjectType( "ScalingOverCenter", argsspecScalingOverCenter, 3 )
 
196
{
 
197
}
 
198
 
 
199
ScalingOverCenterType::~ScalingOverCenterType()
 
200
{
 
201
}
 
202
 
 
203
const ScalingOverCenterType* ScalingOverCenterType::instance()
 
204
{
 
205
  static const ScalingOverCenterType t;
 
206
  return &t;
 
207
}
 
208
 
 
209
ObjectImp* ScalingOverCenterType::calc( const Args& args, const KigDocument& ) const
 
210
{
 
211
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
212
 
 
213
  Coordinate center = static_cast<const PointImp*>( args[1] )->coordinate();
 
214
  bool valid;
 
215
  double ratio = getDoubleFromImp( args[2], valid);
 
216
  if ( ! valid ) return new InvalidImp;
 
217
 
 
218
  return args[0]->transform( Transformation::scalingOverPoint( ratio, center ) );
 
219
}
 
220
 
 
221
static const ArgsParser::spec argsspecScalingOverCenter2[] =
 
222
{
 
223
  { ObjectImp::stype(), I18N_NOOP( "Scale this object" ),
 
224
    I18N_NOOP( "Select the object to scale..." ), false },
 
225
  { PointImp::stype(), I18N_NOOP( "Scale with this center" ),
 
226
    I18N_NOOP( "Select the center point of the scaling..." ), false },
 
227
//  { SegmentImp::stype(), I18N_NOOP( "Scale the length of this segment..." ),
 
228
//    I18N_NOOP( "Select the first of two segments whose ratio is the factor of the scaling..." ), false },
 
229
//  { SegmentImp::stype(), I18N_NOOP( "...to the length of this other segment" ),
 
230
//    I18N_NOOP( "Select the second of two segments whose ratio is the factor of the scaling..." ), false }
 
231
  { &lengthimptypeinstance, I18N_NOOP( "Scale this length..." ),
 
232
    I18N_NOOP( "Select the first of two lengths whose ratio is the factor of the scaling..." ), false },
 
233
  { &lengthimptypeinstance, I18N_NOOP( "...to this other length" ),
 
234
    I18N_NOOP( "Select the second of two lengths whose ratio is the factor of the scaling..." ), false }
 
235
};
 
236
 
 
237
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ScalingOverCenter2Type )
 
238
 
 
239
ScalingOverCenter2Type::ScalingOverCenter2Type()
 
240
  : ArgsParserObjectType( "ScalingOverCenter2", argsspecScalingOverCenter2, 4 )
 
241
{
 
242
}
 
243
 
 
244
ScalingOverCenter2Type::~ScalingOverCenter2Type()
 
245
{
 
246
}
 
247
 
 
248
const ScalingOverCenter2Type* ScalingOverCenter2Type::instance()
 
249
{
 
250
  static const ScalingOverCenter2Type t;
 
251
  return &t;
 
252
}
 
253
 
 
254
ObjectImp* ScalingOverCenter2Type::calc( const Args& args, const KigDocument& ) const
 
255
{
 
256
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
257
 
 
258
  Coordinate center = static_cast<const PointImp*>( args[1] )->coordinate();
 
259
//  double ratio = static_cast<const SegmentImp*>( args[3] )->length()/
 
260
//                 static_cast<const SegmentImp*>( args[2] )->length();
 
261
  bool valid;
 
262
  double denom = getDoubleFromImp( args[2], valid );
 
263
  if ( ! valid || denom == 0.0 ) return new InvalidImp;
 
264
  double ratio = getDoubleFromImp( args[3], valid )/denom;
 
265
  if ( ! valid ) return new InvalidImp;
 
266
 
 
267
  return args[0]->transform( Transformation::scalingOverPoint( ratio, center ) );
 
268
}
 
269
 
 
270
static const ArgsParser::spec argsspecScalingOverLine[] =
 
271
{
 
272
  { ObjectImp::stype(), I18N_NOOP( "Scale this object" ), I18N_NOOP( "Select the object to scale" ), false },
 
273
  { AbstractLineImp::stype(), I18N_NOOP( "Scale over this line" ), I18N_NOOP( "Select the line to scale over" ), false },
 
274
//  { SegmentImp::stype(), I18N_NOOP( "Scale by the length of this segment" ), I18N_NOOP( "Select a segment whose length is the factor for the scaling" ), false }
 
275
  { &lengthimptypeinstance, I18N_NOOP( "Scale by this length" ),
 
276
    I18N_NOOP( "Select a length or a segment whose length is the factor of the scaling..." ), false }
 
277
};
 
278
 
 
279
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ScalingOverLineType )
 
280
 
 
281
ScalingOverLineType::ScalingOverLineType()
 
282
  : ArgsParserObjectType( "ScalingOverLine", argsspecScalingOverLine, 3 )
 
283
{
 
284
}
 
285
 
 
286
ScalingOverLineType::~ScalingOverLineType()
 
287
{
 
288
}
 
289
 
 
290
const ScalingOverLineType* ScalingOverLineType::instance()
 
291
{
 
292
  static const ScalingOverLineType t;
 
293
  return &t;
 
294
}
 
295
 
 
296
ObjectImp* ScalingOverLineType::calc( const Args& args, const KigDocument& ) const
 
297
{
 
298
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
299
 
 
300
  LineData line = static_cast<const AbstractLineImp*>( args[1] )->data();
 
301
  bool valid;
 
302
  double ratio = getDoubleFromImp( args[2], valid);
 
303
  if ( ! valid ) return new InvalidImp;
 
304
 
 
305
  return args[0]->transform( Transformation::scalingOverLine( ratio, line ) );
 
306
}
 
307
 
 
308
static const ArgsParser::spec argsspecScalingOverLine2[] =
 
309
{
 
310
  { ObjectImp::stype(), I18N_NOOP( "Scale this object" ), I18N_NOOP( "Select the object to scale" ), false },
 
311
  { AbstractLineImp::stype(), I18N_NOOP( "Scale over this line" ), I18N_NOOP( "Select the line to scale over" ), false },
 
312
//  { SegmentImp::stype(), I18N_NOOP( "Scale the length of this segment..." ), I18N_NOOP( "Select the first of two segments whose ratio is the factor for the scaling" ), false },
 
313
//  { SegmentImp::stype(), I18N_NOOP( "...to the length of this segment" ), I18N_NOOP( "Select the second of two segments whose ratio is the factor for the scaling" ), false }
 
314
  { &lengthimptypeinstance, I18N_NOOP( "Scale this length..." ),
 
315
    I18N_NOOP( "Select the first of two lengths whose ratio is the factor of the scaling..." ), false },
 
316
  { &lengthimptypeinstance, I18N_NOOP( "...to this other length" ),
 
317
    I18N_NOOP( "Select the second of two lengths whose ratio is the factor of the scaling..." ), false }
 
318
};
 
319
 
 
320
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ScalingOverLine2Type )
 
321
 
 
322
ScalingOverLine2Type::ScalingOverLine2Type()
 
323
  : ArgsParserObjectType( "ScalingOverLine2", argsspecScalingOverLine2, 4 )
 
324
{
 
325
}
 
326
 
 
327
ScalingOverLine2Type::~ScalingOverLine2Type()
 
328
{
 
329
}
 
330
 
 
331
const ScalingOverLine2Type* ScalingOverLine2Type::instance()
 
332
{
 
333
  static const ScalingOverLine2Type t;
 
334
  return &t;
 
335
}
 
336
 
 
337
ObjectImp* ScalingOverLine2Type::calc( const Args& args, const KigDocument& ) const
 
338
{
 
339
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
340
 
 
341
  LineData line = static_cast<const AbstractLineImp*>( args[1] )->data();
 
342
//  double ratio = static_cast<const SegmentImp*>( args[3] )->length()/
 
343
//                 static_cast<const SegmentImp*>( args[2] )->length();
 
344
  bool valid;
 
345
  double denom = getDoubleFromImp( args[2], valid );
 
346
  if ( ! valid || denom == 0.0 ) return new InvalidImp;
 
347
  double ratio = getDoubleFromImp( args[3], valid )/denom;
 
348
  if ( ! valid ) return new InvalidImp;
 
349
 
 
350
  return args[0]->transform( Transformation::scalingOverLine( ratio, line ) );
 
351
}
 
352
 
 
353
static const ArgsParser::spec argsspecProjectiveRotation[] =
 
354
{
 
355
  { ObjectImp::stype(), I18N_NOOP( "Projectively rotate this object" ), I18N_NOOP( "Select the object to rotate projectively" ), false },
 
356
  { RayImp::stype(), I18N_NOOP( "Projectively rotate with this half-line" ), I18N_NOOP( "Select the half line of the projective rotation that you want to apply to the object" ), false },
 
357
  { AngleImp::stype(), I18N_NOOP( "Projectively rotate by this angle" ), I18N_NOOP( "Select the angle of the projective rotation that you want to apply to the object" ), false }
 
358
};
 
359
 
 
360
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ProjectiveRotationType )
 
361
 
 
362
ProjectiveRotationType::ProjectiveRotationType()
 
363
  : ArgsParserObjectType( "ProjectiveRotation", argsspecProjectiveRotation, 3 )
 
364
{
 
365
}
 
366
 
 
367
ProjectiveRotationType::~ProjectiveRotationType()
 
368
{
 
369
}
 
370
 
 
371
const ProjectiveRotationType* ProjectiveRotationType::instance()
 
372
{
 
373
  static const ProjectiveRotationType t;
 
374
  return &t;
 
375
}
 
376
 
 
377
ObjectImp* ProjectiveRotationType::calc( const Args& args, const KigDocument& ) const
 
378
{
 
379
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
380
 
 
381
  const RayImp* ray = static_cast<const RayImp*>( args[1] );
 
382
  Coordinate c1 = ray->data().a;
 
383
  Coordinate dir = ray->data().dir().normalize();
 
384
  double alpha = static_cast<const AngleImp*>( args[2] )->size();
 
385
 
 
386
  return args[0]->transform(
 
387
    Transformation::projectiveRotation( alpha, dir, c1 ) );
 
388
}
 
389
 
 
390
static const ArgsParser::spec argsspecHarmonicHomology[] =
 
391
{
 
392
  { ObjectImp::stype(), I18N_NOOP( "Harmonic Homology of this object" ),
 
393
    I18N_NOOP( "Select the object to transform..." ), false },
 
394
  { PointImp::stype(), I18N_NOOP( "Harmonic Homology with this center" ),
 
395
    I18N_NOOP( "Select the center point of the harmonic homology..." ), false },
 
396
  { AbstractLineImp::stype(), I18N_NOOP( "Harmonic Homology with this axis" ),
 
397
    I18N_NOOP( "Select the axis of the harmonic homology..." ), false }
 
398
};
 
399
 
 
400
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( HarmonicHomologyType )
 
401
 
 
402
HarmonicHomologyType::HarmonicHomologyType()
 
403
  : ArgsParserObjectType( "HarmonicHomology", argsspecHarmonicHomology, 3 )
 
404
{
 
405
}
 
406
 
 
407
HarmonicHomologyType::~HarmonicHomologyType()
 
408
{
 
409
}
 
410
 
 
411
const HarmonicHomologyType* HarmonicHomologyType::instance()
 
412
{
 
413
  static const HarmonicHomologyType t;
 
414
  return &t;
 
415
}
 
416
 
 
417
ObjectImp* HarmonicHomologyType::calc( const Args& args, const KigDocument& ) const
 
418
{
 
419
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
420
 
 
421
  Coordinate center = static_cast<const PointImp*>( args[1] )->coordinate();
 
422
  LineData axis = static_cast<const AbstractLineImp*>( args[2] )->data();
 
423
  return args[0]->transform(
 
424
    Transformation::harmonicHomology( center, axis ) );
 
425
}
 
426
 
 
427
static const ArgsParser::spec argsspecAffinityB2Tr[] =
 
428
{
 
429
  { ObjectImp::stype(), I18N_NOOP( "Generic affinity of this object" ),
 
430
    I18N_NOOP( "Select the object to transform..." ), false },
 
431
  { FilledPolygonImp::stype3(), I18N_NOOP( "Map this triangle" ),
 
432
    I18N_NOOP( "Select the triangle that has to be transformed onto a given triangle..." ), false },
 
433
  { FilledPolygonImp::stype3(), I18N_NOOP( "onto this other triangle" ),
 
434
    I18N_NOOP( "Select the triangle that is the image by the affinity of the first triangle..." ), false }
 
435
};
 
436
 
 
437
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( AffinityB2TrType )
 
438
 
 
439
AffinityB2TrType::AffinityB2TrType()
 
440
  : ArgsParserObjectType( "AffinityB2Tr", argsspecAffinityB2Tr, 3 )
 
441
{
 
442
}
 
443
 
 
444
AffinityB2TrType::~AffinityB2TrType()
 
445
{
 
446
}
 
447
 
 
448
const AffinityB2TrType* AffinityB2TrType::instance()
 
449
{
 
450
  static const AffinityB2TrType t;
 
451
  return &t;
 
452
}
 
453
 
 
454
ObjectImp* AffinityB2TrType::calc( const Args& args, const KigDocument& ) const
 
455
{
 
456
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
457
 
 
458
  std::vector<Coordinate> frompoints = static_cast<const FilledPolygonImp*>( args[1] )->points();
 
459
  std::vector<Coordinate> topoints = static_cast<const FilledPolygonImp*>( args[2] )->points();
 
460
 
 
461
  bool valid = true;
 
462
  Transformation t = Transformation::affinityGI3P( frompoints, topoints,
 
463
        valid );
 
464
 
 
465
  if (valid == false) return new InvalidImp;
 
466
  return args[0]->transform( t );
 
467
}
 
468
 
 
469
static const ArgsParser::spec argsspecAffinityGI3P[] =
 
470
{
 
471
  { ObjectImp::stype(), I18N_NOOP( "Generic affinity of this object" ),
 
472
    I18N_NOOP( "Select the object to transform..." ), false },
 
473
  { PointImp::stype(), I18N_NOOP( "First of 3 starting points" ),
 
474
    I18N_NOOP( "Select the first of the three starting points of the generic affinity..." ), false },
 
475
  { PointImp::stype(), I18N_NOOP( "Second of 3 starting points" ),
 
476
    I18N_NOOP( "Select the second of the three starting points of the generic affinity..." ), false },
 
477
  { PointImp::stype(), I18N_NOOP( "Third of 3 starting points" ),
 
478
    I18N_NOOP( "Select the third of the three starting points of the generic affinity..." ), false },
 
479
  { PointImp::stype(), I18N_NOOP( "Transformed position of first point" ),
 
480
    I18N_NOOP( "Select the first of the three end points of the generic affinity..." ), false },
 
481
  { PointImp::stype(), I18N_NOOP( "Transformed position of second point" ),
 
482
    I18N_NOOP( "Select the second of the three end points of the generic affinity..." ), false },
 
483
  { PointImp::stype(), I18N_NOOP( "Transformed position of third point" ),
 
484
    I18N_NOOP( "Select the third of the three end points of the generic affinity..." ), false },
 
485
};
 
486
 
 
487
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( AffinityGI3PType )
 
488
 
 
489
AffinityGI3PType::AffinityGI3PType()
 
490
  : ArgsParserObjectType( "AffinityGI3P", argsspecAffinityGI3P, 7 )
 
491
{
 
492
}
 
493
 
 
494
AffinityGI3PType::~AffinityGI3PType()
 
495
{
 
496
}
 
497
 
 
498
const AffinityGI3PType* AffinityGI3PType::instance()
 
499
{
 
500
  static const AffinityGI3PType t;
 
501
  return &t;
 
502
}
 
503
 
 
504
ObjectImp* AffinityGI3PType::calc( const Args& args, const KigDocument& ) const
 
505
{
 
506
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
507
 
 
508
  std::vector<Coordinate> frompoints;
 
509
  std::vector<Coordinate> topoints;
 
510
  for ( uint i = 0; i < 3; ++i )
 
511
  {
 
512
    frompoints.push_back(
 
513
           static_cast<const PointImp*>( args[i+1] )->coordinate() );
 
514
    topoints.push_back(
 
515
           static_cast<const PointImp*>( args[i+4] )->coordinate() );
 
516
  }
 
517
 
 
518
  bool valid = true;
 
519
  Transformation t = Transformation::affinityGI3P( frompoints, topoints,
 
520
        valid );
 
521
 
 
522
  if (valid == false) return new InvalidImp;
 
523
  return args[0]->transform( t );
 
524
}
 
525
 
 
526
static const ArgsParser::spec argsspecProjectivityB2Qu[] =
 
527
{
 
528
  { ObjectImp::stype(), I18N_NOOP( "Generic projective transformation of this object" ),
 
529
    I18N_NOOP( "Select the object to transform..." ), false },
 
530
  { FilledPolygonImp::stype4(), I18N_NOOP( "Map this quadrilateral" ),
 
531
    I18N_NOOP( "Select the quadrilateral that has to be transformed onto a given quadrilateral..." ), false },
 
532
  { FilledPolygonImp::stype4(), I18N_NOOP( "onto this other quadrilateral" ),
 
533
    I18N_NOOP( "Select the quadrilateral that is the image by the projective transformation of the first quadrilateral..." ), false }
 
534
};
 
535
 
 
536
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ProjectivityB2QuType )
 
537
 
 
538
ProjectivityB2QuType::ProjectivityB2QuType()
 
539
  : ArgsParserObjectType( "ProjectivityB2Qu", argsspecProjectivityB2Qu, 3 )
 
540
{
 
541
}
 
542
 
 
543
ProjectivityB2QuType::~ProjectivityB2QuType()
 
544
{
 
545
}
 
546
 
 
547
const ProjectivityB2QuType* ProjectivityB2QuType::instance()
 
548
{
 
549
  static const ProjectivityB2QuType t;
 
550
  return &t;
 
551
}
 
552
 
 
553
ObjectImp* ProjectivityB2QuType::calc( const Args& args, const KigDocument& ) const
 
554
{
 
555
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
556
 
 
557
  std::vector<Coordinate> frompoints = static_cast<const FilledPolygonImp*>( args[1] )->points();
 
558
  std::vector<Coordinate> topoints = static_cast<const FilledPolygonImp*>( args[2] )->points();
 
559
 
 
560
  bool valid = true;
 
561
  Transformation t = Transformation::projectivityGI4P( frompoints, topoints,
 
562
        valid );
 
563
 
 
564
  if (valid == false) return new InvalidImp;
 
565
  return args[0]->transform( t );
 
566
}
 
567
 
 
568
static const ArgsParser::spec argsspecProjectivityGI4P[] =
 
569
{
 
570
  { ObjectImp::stype(), I18N_NOOP( "Generic projective transformation of this object" ),
 
571
    I18N_NOOP( "Select the object to transform..." ), false },
 
572
  { PointImp::stype(), I18N_NOOP( "First of 4 starting points" ),
 
573
    I18N_NOOP( "Select the first of the four starting points of the generic projectivity..." ), false },
 
574
  { PointImp::stype(), I18N_NOOP( "Second of 4 starting points" ),
 
575
    I18N_NOOP( "Select the second of the four starting points of the generic projectivity..." ), false },
 
576
  { PointImp::stype(), I18N_NOOP( "Third of 4 starting points" ),
 
577
    I18N_NOOP( "Select the third of the four starting points of the generic projectivity..." ), false },
 
578
  { PointImp::stype(), I18N_NOOP( "Fourth of 4 starting points" ),
 
579
    I18N_NOOP( "Select the fourth of the four starting points of the generic projectivity..." ), false },
 
580
  { PointImp::stype(), I18N_NOOP( "Transformed position of first point" ),
 
581
    I18N_NOOP( "Select the first of the four end points of the generic projectivity..." ), false },
 
582
  { PointImp::stype(), I18N_NOOP( "Transformed position of second point" ),
 
583
    I18N_NOOP( "Select the second of the four end points of the generic projectivity..." ), false },
 
584
  { PointImp::stype(), I18N_NOOP( "Transformed position of third point" ),
 
585
    I18N_NOOP( "Select the third of the four end points of the generic projectivity..." ), false },
 
586
  { PointImp::stype(), I18N_NOOP( "Transformed position of fourth point" ),
 
587
    I18N_NOOP( "Select the fourth of the four end points of the generic projectivity..." ), false }
 
588
};
 
589
 
 
590
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ProjectivityGI4PType )
 
591
 
 
592
ProjectivityGI4PType::ProjectivityGI4PType()
 
593
  : ArgsParserObjectType( "ProjectivityGI4P", argsspecProjectivityGI4P, 9 )
 
594
{
 
595
}
 
596
 
 
597
ProjectivityGI4PType::~ProjectivityGI4PType()
 
598
{
 
599
}
 
600
 
 
601
const ProjectivityGI4PType* ProjectivityGI4PType::instance()
 
602
{
 
603
  static const ProjectivityGI4PType t;
 
604
  return &t;
 
605
}
 
606
 
 
607
ObjectImp* ProjectivityGI4PType::calc( const Args& args, const KigDocument& ) const
 
608
{
 
609
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
610
 
 
611
  std::vector<Coordinate> frompoints;
 
612
  std::vector<Coordinate> topoints;
 
613
  for ( uint i = 0; i < 4; ++i )
 
614
  {
 
615
    frompoints.push_back(
 
616
           static_cast<const PointImp*>( args[i+1] )->coordinate() );
 
617
    topoints.push_back(
 
618
           static_cast<const PointImp*>( args[i+5] )->coordinate() );
 
619
  }
 
620
 
 
621
  bool valid = true;
 
622
  Transformation t = Transformation::projectivityGI4P( frompoints, topoints,
 
623
        valid );
 
624
 
 
625
  if (valid == false) return new InvalidImp;
 
626
  return args[0]->transform( t );
 
627
}
 
628
 
 
629
static const ArgsParser::spec argsspecCastShadow[] =
 
630
{
 
631
  { ObjectImp::stype(), I18N_NOOP( "Cast the shadow of this object" ),
 
632
    I18N_NOOP( "Select the object of which you want to construct the shadow..." ), false },
 
633
  { PointImp::stype(), I18N_NOOP( "Cast a shadow from this light source" ),
 
634
    I18N_NOOP( "Select the light source from which the shadow should originate..." ), false },
 
635
  { AbstractLineImp::stype(),
 
636
    I18N_NOOP( "Cast a shadow on the horizon represented by this line" ),
 
637
    I18N_NOOP( "Select the horizon for the shadow..." ), false }
 
638
};
 
639
 
 
640
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( CastShadowType )
 
641
 
 
642
CastShadowType::CastShadowType()
 
643
  : ArgsParserObjectType( "CastShadow", argsspecCastShadow, 3 )
 
644
{
 
645
}
 
646
 
 
647
CastShadowType::~CastShadowType()
 
648
{
 
649
}
 
650
 
 
651
const CastShadowType* CastShadowType::instance()
 
652
{
 
653
  static const CastShadowType t;
 
654
  return &t;
 
655
}
 
656
 
 
657
ObjectImp* CastShadowType::calc( const Args& args, const KigDocument& ) const
 
658
{
 
659
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
660
 
 
661
  Coordinate lightsrc = static_cast<const PointImp*>( args[1] )->coordinate();
 
662
  LineData d = static_cast<const AbstractLineImp*>( args[2] )->data();
 
663
  return args[0]->transform(
 
664
    Transformation::castShadow( lightsrc, d ) );
 
665
}
 
666
 
 
667
const ObjectImpType* TranslatedType::resultId() const
 
668
{
 
669
  return ObjectImp::stype();
 
670
}
 
671
 
 
672
const ObjectImpType* PointReflectionType::resultId() const
 
673
{
 
674
  return ObjectImp::stype();
 
675
}
 
676
 
 
677
const ObjectImpType* LineReflectionType::resultId() const
 
678
{
 
679
  return ObjectImp::stype();
 
680
}
 
681
 
 
682
const ObjectImpType* RotationType::resultId() const
 
683
{
 
684
  return ObjectImp::stype();
 
685
}
 
686
 
 
687
const ObjectImpType* ScalingOverCenterType::resultId() const
 
688
{
 
689
  return ObjectImp::stype();
 
690
}
 
691
 
 
692
const ObjectImpType* ScalingOverCenter2Type::resultId() const
 
693
{
 
694
  return ObjectImp::stype();
 
695
}
 
696
 
 
697
const ObjectImpType* ScalingOverLineType::resultId() const
 
698
{
 
699
  return ObjectImp::stype();
 
700
}
 
701
 
 
702
const ObjectImpType* ScalingOverLine2Type::resultId() const
 
703
{
 
704
  return ObjectImp::stype();
 
705
}
 
706
 
 
707
const ObjectImpType* ProjectiveRotationType::resultId() const
 
708
{
 
709
  return ObjectImp::stype();
 
710
}
 
711
 
 
712
const ObjectImpType* HarmonicHomologyType::resultId() const
 
713
{
 
714
  return ObjectImp::stype();
 
715
}
 
716
 
 
717
const ObjectImpType* AffinityB2TrType::resultId() const
 
718
{
 
719
  return ObjectImp::stype();
 
720
}
 
721
 
 
722
const ObjectImpType* AffinityGI3PType::resultId() const
 
723
{
 
724
  return ObjectImp::stype();
 
725
}
 
726
 
 
727
const ObjectImpType* ProjectivityB2QuType::resultId() const
 
728
{
 
729
  return ObjectImp::stype();
 
730
}
 
731
 
 
732
const ObjectImpType* ProjectivityGI4PType::resultId() const
 
733
{
 
734
  return ObjectImp::stype();
 
735
}
 
736
 
 
737
const ObjectImpType* CastShadowType::resultId() const
 
738
{
 
739
  return ObjectImp::stype();
 
740
}
 
741
 
 
742
bool TranslatedType::isTransform() const
 
743
{
 
744
  return true;
 
745
}
 
746
 
 
747
bool PointReflectionType::isTransform() const
 
748
{
 
749
  return true;
 
750
}
 
751
 
 
752
bool LineReflectionType::isTransform() const
 
753
{
 
754
  return true;
 
755
}
 
756
 
 
757
bool RotationType::isTransform() const
 
758
{
 
759
  return true;
 
760
}
 
761
 
 
762
bool ScalingOverCenterType::isTransform() const
 
763
{
 
764
  return true;
 
765
}
 
766
 
 
767
bool ScalingOverCenter2Type::isTransform() const
 
768
{
 
769
  return true;
 
770
}
 
771
 
 
772
bool ScalingOverLineType::isTransform() const
 
773
{
 
774
  return true;
 
775
}
 
776
 
 
777
bool ScalingOverLine2Type::isTransform() const
 
778
{
 
779
  return true;
 
780
}
 
781
 
 
782
bool ProjectiveRotationType::isTransform() const
 
783
{
 
784
  return true;
 
785
}
 
786
 
 
787
bool HarmonicHomologyType::isTransform() const
 
788
{
 
789
  return true;
 
790
}
 
791
 
 
792
bool AffinityB2TrType::isTransform() const
 
793
{
 
794
  return true;
 
795
}
 
796
 
 
797
bool AffinityGI3PType::isTransform() const
 
798
{
 
799
  return true;
 
800
}
 
801
 
 
802
bool ProjectivityB2QuType::isTransform() const
 
803
{
 
804
  return true;
 
805
}
 
806
 
 
807
bool ProjectivityGI4PType::isTransform() const
 
808
{
 
809
  return true;
 
810
}
 
811
 
 
812
bool CastShadowType::isTransform() const
 
813
{
 
814
  return true;
 
815
}
 
816
 
 
817
static const ArgsParser::spec argsspecApplyTransformation[] =
 
818
{
 
819
  { ObjectImp::stype(), I18N_NOOP( "Transform this object" ), "SHOULD NOT BE SEEN", false },
 
820
  { TransformationImp::stype(), I18N_NOOP( "Transform using this transformation" ), "SHOULD NOT BE SEEN", false }
 
821
};
 
822
 
 
823
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ApplyTransformationObjectType )
 
824
 
 
825
ApplyTransformationObjectType::ApplyTransformationObjectType()
 
826
  : ArgsParserObjectType( "ApplyTransformation", argsspecApplyTransformation, 2 )
 
827
{
 
828
}
 
829
 
 
830
ApplyTransformationObjectType::~ApplyTransformationObjectType()
 
831
{
 
832
}
 
833
 
 
834
const ApplyTransformationObjectType* ApplyTransformationObjectType::instance()
 
835
{
 
836
  static const ApplyTransformationObjectType t;
 
837
  return &t;
 
838
}
 
839
 
 
840
ObjectImp* ApplyTransformationObjectType::calc( const Args& args, const KigDocument& ) const
 
841
{
 
842
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
843
  return args[0]->transform( static_cast<const TransformationImp*>( args[1] )->data() );
 
844
}
 
845
 
 
846
const ObjectImpType* ApplyTransformationObjectType::resultId() const
 
847
{
 
848
  return ObjectImp::stype();
 
849
}
 
850
 
 
851
bool ApplyTransformationObjectType::isTransform() const
 
852
{
 
853
  return true;
 
854
}
 
855
 
 
856
bool SimilitudeType::isTransform() const
 
857
{
 
858
  return true;
 
859
}
 
860
 
 
861
const ObjectImpType* SimilitudeType::resultId() const
 
862
{
 
863
  return ObjectImp::stype();
 
864
}
 
865
 
 
866
const SimilitudeType* SimilitudeType::instance()
 
867
{
 
868
  static const SimilitudeType t;
 
869
  return &t;
 
870
}
 
871
 
 
872
ObjectImp* SimilitudeType::calc( const Args& args, const KigDocument& ) const
 
873
{
 
874
  if ( ! margsparser.checkArgs( args ) ) return new InvalidImp;
 
875
 
 
876
  Coordinate c = static_cast<const PointImp*>( args[1] )->coordinate();
 
877
  Coordinate a = static_cast<const PointImp*>( args[2] )->coordinate();
 
878
  Coordinate b = static_cast<const PointImp*>( args[3] )->coordinate();
 
879
  a -= c;
 
880
  b -= c;
 
881
  double factor = sqrt( b.squareLength()/a.squareLength() );
 
882
  double theta = atan2( b.y, b.x ) - atan2( a.y, a.x );
 
883
 
 
884
  return args[0]->transform( Transformation::similitude( c, theta, factor ) );
 
885
}
 
886
 
 
887
SimilitudeType::~SimilitudeType()
 
888
{
 
889
}
 
890
 
 
891
static const ArgsParser::spec argsspecSimilitude[] =
 
892
{
 
893
  { ObjectImp::stype(), I18N_NOOP( "Apply a similitude to this object" ),
 
894
    I18N_NOOP( "Select the object to transform..." ), false },
 
895
  { PointImp::stype(), I18N_NOOP( "Apply a similitude with this center" ),
 
896
    I18N_NOOP( "Select the center for the similitude..." ), false },
 
897
  { PointImp::stype(), I18N_NOOP( "Apply a similitude mapping this point onto another point" ),
 
898
    I18N_NOOP( "Select the point which the similitude should map onto another point..." ), false },
 
899
  { PointImp::stype(), I18N_NOOP( "Apply a similitude mapping a point onto this point" ),
 
900
    I18N_NOOP( "Select the point onto which the similitude should map the first point..." ), false }
 
901
};
 
902
 
 
903
KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( SimilitudeType )
 
904
 
 
905
SimilitudeType::SimilitudeType()
 
906
  : ArgsParserObjectType( "Similitude", argsspecSimilitude, 4 )
 
907
{
 
908
}