6
6
This file is part of the extensible drawing editor Ipe.
7
Copyright (C) 1993-2007 Otfried Cheong
7
Copyright (C) 1993-2009 Otfried Cheong
9
9
Ipe is free software; you can redistribute it and/or modify it
10
10
under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
11
the Free Software Foundation; either version 3 of the License, or
12
12
(at your option) any later version.
14
14
As a special exception, you have permission to link Ipe with the
31
31
#include "ipelet.h"
32
32
#include "ipepath.h"
33
33
#include "ipepage.h"
34
#include "ipevisitor.h"
36
37
// --------------------------------------------------------------------
38
39
class KGonIpelet : public Ipelet {
40
virtual int IpelibVersion() const { return IPELIB_VERSION; }
41
virtual const char *Label() const { return "Regular k-gon"; }
42
virtual void Run(int, IpePage *page, IpeletHelper *helper);
41
virtual int ipelibVersion() const { return IPELIB_VERSION; }
42
virtual bool run(int, IpeletData *data, IpeletHelper *helper);
45
45
// --------------------------------------------------------------------
47
void KGonIpelet::Run(int, IpePage *page, IpeletHelper *helper)
47
bool KGonIpelet::run(int, IpeletData *data, IpeletHelper *helper)
49
IpePage::iterator it = page->PrimarySelection();
50
if (it == page->end() || !it->Object()->AsPath() ||
51
it->Object()->AsPath()->NumSubPaths() > 1 ||
52
it->Object()->AsPath()->SubPath(0)->Type() != IpeSubPath::EEllipse) {
53
helper->Message("Primary selection is not a circle");
49
Page *page = data->iPage;
50
int sel = page->primarySelection();
52
helper->message("No selection");
55
const Path *p = page->object(sel)->asPath();
56
if (p == 0 || p->shape().countSubPaths() != 1 ||
57
p->shape().subPath(0)->type() != SubPath::EEllipse) {
58
helper->message("Primary selection is not a circle");
58
if (!helper->GetString("Enter k (number of corners)", str))
63
if (!helper->getString("Enter k (number of corners)", str))
65
int k = Lex(str).getInt();
63
66
if (k < 3 || k > 1000)
66
const IpePath *p = it->Object()->AsPath();
67
const IpeEllipse *e = p->SubPath(0)->AsEllipse();
68
IpeMatrix m = p->Matrix() * e->Matrix();
70
IpeVector center = m.Translation();
71
IpeVector v = m * IpeVector(1,0);
72
double radius = (v - center).Len();
74
IpeSegmentSubPath *sp = new IpeSegmentSubPath;
69
const Ellipse *e = p->shape().subPath(0)->asEllipse();
70
Matrix m = p->matrix() * e->matrix();
72
Vector center = m.translation();
73
Vector v = m * Vector(1,0);
74
double radius = (v - center).len();
76
Curve *sp = new Curve;
75
77
double alpha = 2.0 * IpePi / k;
76
IpeVector v0 = center + radius * IpeVector(1,0);
78
Vector v0 = center + radius * Vector(1,0);
77
79
for (int i = 1; i < k; ++i) {
78
IpeVector v1 = center + radius * IpeVector(IpeAngle(i * alpha));
79
sp->AppendSegment(v0, v1);
80
Vector v1 = center + radius * Vector(Angle(i * alpha));
81
sp->appendSegment(v0, v1);
83
IpePath *obj = new IpePath(helper->Attributes());
85
page->push_back(IpePgObject(IpePgObject::ESecondary,
86
helper->CurrentLayer(), obj));
87
helper->Message("Created regular k-gon");
86
shape.appendSubPath(sp);
87
Path *obj = new Path(data->iAttributes, shape);
88
page->append(ESecondarySelected, data->iLayer, obj);
89
helper->message("Created regular k-gon");
90
93
// --------------------------------------------------------------------
92
IPELET_DECLARE Ipelet *NewIpelet()
95
IPELET_DECLARE Ipelet *newIpelet()
94
97
return new KGonIpelet;