1 /**********************************************************************
2 *
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
5 *
6 * Copyright (C) 2001-2002 Vivid Solutions Inc.
7 *
8 * This is free software; you can redistribute and/or modify it under
9 * the terms of the GNU Lesser General Public Licence as published
10 * by the Free Software Foundation.
11 * See the COPYING file for more information.
12 *
13 **********************************************************************/
14
15 #include <cmath>
16
17 #include <geos/geom/GeometryFactory.h>
18 #include <geos/geom/CoordinateArraySequence.h>
19 #include <geos/geom/Coordinate.h>
20 #include "bigtest.h"
21
22 #define PI 3.14159265358979
23
24 using namespace geos::geom;
25
26 Polygon*
createBox(GeometryFactory * fact,double minx,double miny,int nSide,double segLen)27 GeometryTestFactory::createBox(GeometryFactory* fact, double minx, double miny, int nSide, double segLen)
28 {
29 CoordinateSequence* pts = createBox(minx, miny, nSide, segLen);
30 return fact->createPolygon(fact->createLinearRing(pts), nullptr);
31 }
32
33 CoordinateSequence*
createBox(double minx,double miny,int nSide,double segLen)34 GeometryTestFactory::createBox(double minx, double miny, int nSide, double segLen)
35 {
36 int i;
37 CoordinateArraySequence* pts = new CoordinateArraySequence();
38 double maxx = minx + nSide * segLen;
39 double maxy = miny + nSide * segLen;
40
41 for(i = 0; i < nSide; i++) {
42 double x = minx + i * segLen;
43 double y = miny;
44 pts->add(Coordinate(x, y));
45 }
46 for(i = 0; i < nSide; i++) {
47 double x = maxx;
48 double y = miny + i * segLen;
49 pts->add(Coordinate(x, y));
50 }
51 for(i = 0; i < nSide; i++) {
52 double x = maxx - i * segLen;
53 double y = maxy;
54 pts->add(Coordinate(x, y));
55 }
56 for(i = 0; i < nSide; i++) {
57 double x = minx;
58 double y = maxy - i * segLen;
59 pts->add(Coordinate(x, y));
60 }
61 pts->add(pts->getAt(0));
62 return pts;
63 }
64
65 /**
66 * Creates a circle
67 * @param x the centre x coord
68 * @param y the centre y coord
69 * @param size the size of the envelope of the star
70 * @param nPts the number of points in the star
71 */
72 CoordinateSequence*
createCircle(double basex,double basey,double size,uint32_t nPts)73 GeometryTestFactory::createCircle(double basex, double basey, double size, uint32_t nPts)
74 {
75 CoordinateArraySequence* pts = new CoordinateArraySequence(nPts + 1);
76 double len = size / 2.0;
77
78 for(int i = 0; i < nPts; i++) {
79 double ang = i * (2 * PI / nPts);
80 double x = len * cos(ang) + basex;
81 double y = len * sin(ang) + basey;
82 pts->add(Coordinate(x, y));
83 }
84 pts->add(Coordinate(pts->getAt(0)));
85 return pts;
86 }
87
88 Polygon*
createCircle(GeometryFactory * fact,double basex,double basey,double size,uint32_t nPts)89 GeometryTestFactory::createCircle(GeometryFactory* fact, double basex, double basey, double size, uint32_t nPts)
90 {
91 CoordinateSequence* pts = createCircle(basex, basey, size, nPts);
92 return fact->createPolygon(fact->createLinearRing(pts), nullptr);
93 }
94
95 /**
96 * Creates a star from a "circular" sine wave
97 * @param basex the centre x coord
98 * @param basey the centre y coord
99 * @param size the size of the envelope of the star
100 * @param armLen the length of an arm of the star
101 * @param nArms the number of arms of the star
102 * @param nPts the number of points in the star
103 */
104 CoordinateSequence*
createSineStar(double basex,double basey,double size,double armLen,int nArms,int nPts)105 GeometryTestFactory::createSineStar(double basex, double basey, double size, double armLen, int nArms, int nPts)
106 {
107 double armBaseLen = size / 2 - armLen;
108 if(armBaseLen < 0) {
109 armBaseLen = 0.5;
110 }
111
112 double angInc = 2 * PI / nArms;
113 int nArmPt = nPts / nArms;
114 if(nArmPt < 5) {
115 nArmPt = 5;
116 }
117
118 //int nPts2=nArmPt*nArms;
119 CoordinateArraySequence* pts = new CoordinateArraySequence();
120
121 double starAng = 0.0;
122
123 for(int iArm = 0; iArm < nArms; iArm++) {
124 for(int iArmPt = 0; iArmPt < nArmPt; iArmPt++) {
125 double ang = iArmPt * (2 * PI / nArmPt);
126 double len = armLen * (1 - cos(ang) / 2) + armBaseLen;
127 double x = len * cos(starAng + iArmPt * angInc / nArmPt) + basex;
128 double y = len * sin(starAng + iArmPt * angInc / nArmPt) + basey;
129
130 // FIXME - mloskot: Number of problems here:
131 // - add() method makes a copy
132 pts->add(Coordinate(x, y));
133 }
134 starAng += angInc;
135 }
136 // FIXME - mloskot: The same problems as above
137 pts->add(pts->getAt(0));
138 return pts;
139 }
140
141 Polygon*
createSineStar(GeometryFactory * fact,double basex,double basey,double size,double armLen,int nArms,int nPts)142 GeometryTestFactory::createSineStar(GeometryFactory* fact, double basex, double basey, double size, double armLen,
143 int nArms, int nPts)
144 {
145 CoordinateSequence* pts = createSineStar(basex, basey, size, armLen, nArms, nPts);
146 return fact->createPolygon(fact->createLinearRing(pts), nullptr);
147 }
148