Geometrize 1.0
C++ library for geometrizing images into geometric primitives
Namespaces | Classes | Typedefs | Enumerations | Functions | Variables
geometrize Namespace Reference

Namespaces

namespace  commonutil
 
namespace  core
 
namespace  exporter
 

Classes

class  Bitmap
 The Bitmap class is a helper class for working with bitmap data. More...
 
class  Circle
 The Circle class represents a circle. More...
 
class  Ellipse
 The Ellipse class represents an ellipse. More...
 
class  ImageRunner
 The ImageRunner class is a helper class for creating a set of primitives from a source image. More...
 
class  ImageRunnerOptions
 The ImageRunnerOptions class encapsulates preferences/options that the image runner uses. More...
 
struct  ImageRunnerShapeBoundsOptions
 The ImageRunnerShapeBoundsOptions struct encapsulates options for where shapes may be drawn within the image. Defines a rectangle expressed as percentages (0-100%) of the target image dimensions. More...
 
class  Line
 The Line class represents a simple line. More...
 
class  Model
 The Model class is the model for the core optimization/fitting algorithm. More...
 
class  Polyline
 The Polyline class represents a polyline. More...
 
class  QuadraticBezier
 The QuadraticBezier class represents a quadratic bezier curve. More...
 
class  Rectangle
 The Rectangle class represents a rectangle. More...
 
struct  rgba
 The rgba struct is a helper for manipulating RGBA8888 color data. More...
 
class  RotatedEllipse
 The RotatedEllipse class represents a rotated ellipse. More...
 
class  RotatedRectangle
 The RotatedRectangle class represents a rotated rectangle. More...
 
class  Scanline
 The Scanline class represents a scanline, a row of pixels running across a bitmap. More...
 
class  Shape
 
struct  ShapeResult
 The ShapeResult struct is a container for info about a shape added to the model. More...
 
class  State
 The State class relates a shape and related properties to a measure of how close it brings the working image to the target image. More...
 
class  Triangle
 The Triangle class represents a triangle. More...
 

Typedefs

using ShapeAcceptancePreconditionFunction = std::function< bool(double lastScore, double newScore, const geometrize::Shape &shape, const std::vector< geometrize::Scanline > &lines, const geometrize::rgba &color, const geometrize::Bitmap &before, const geometrize::Bitmap &after, const geometrize::Bitmap &target)>
 ShapeAcceptancePreconditionFunction Type alias for a function that is used to decide whether or not to finally add a shape to the image. More...
 

Enumerations

enum  ShapeTypes : std::uint32_t {
  RECTANGLE = 1U , ROTATED_RECTANGLE = 2U , TRIANGLE = 4U , ELLIPSE = 8U ,
  ROTATED_ELLIPSE = 16U , CIRCLE = 32U , LINE = 64U , QUADRATIC_BEZIER = 128U ,
  POLYLINE = 256U , SHAPE_COUNT = 9U
}
 The ShapeTypes enum specifies the types of shapes that can be used. These can be combined to produce images composed of multiple primitive types. More...
 

Functions

bool operator== (const geometrize::rgba &lhs, const geometrize::rgba &rhs)
 
bool operator!= (const geometrize::rgba &lhs, const geometrize::rgba &rhs)
 
std::vector< float > getRawShapeData (const geometrize::Shape &s)
 
std::vector< float > getRawShapeData (const geometrize::Circle &s)
 
std::vector< float > getRawShapeData (const geometrize::Ellipse &s)
 
std::vector< float > getRawShapeData (const geometrize::Line &s)
 
std::vector< float > getRawShapeData (const geometrize::Polyline &s)
 
std::vector< float > getRawShapeData (const geometrize::QuadraticBezier &s)
 
std::vector< float > getRawShapeData (const geometrize::Rectangle &s)
 
std::vector< float > getRawShapeData (const geometrize::RotatedEllipse &s)
 
std::vector< float > getRawShapeData (const geometrize::RotatedRectangle &s)
 
std::vector< float > getRawShapeData (const geometrize::Triangle &s)
 
std::vector< std::pair< float, float > > getCornerPoints (const geometrize::RotatedRectangle &r)
 getCornerPoints Gets the corner points of the given rotated rectangle. More...
 
std::vector< std::pair< float, float > > getPointsOnRotatedEllipse (const geometrize::RotatedEllipse &e, std::size_t numPoints)
 getPointsOnRotatedEllipse Calculates and returns a number of points on the given rotated ellipse. More...
 
void drawLines (geometrize::Bitmap &image, geometrize::rgba color, const std::vector< geometrize::Scanline > &lines)
 drawLines Draws scanlines onto an image. More...
 
void copyLines (geometrize::Bitmap &destination, const geometrize::Bitmap &source, const std::vector< geometrize::Scanline > &lines)
 copyLines Copies source pixels to a destination defined by a set of scanlines. More...
 
std::vector< std::pair< std::int32_t, std::int32_t > > bresenham (std::int32_t x1, std::int32_t y1, std::int32_t x2, std::int32_t y2)
 bresenham Bresenham's line algorithm. Returns the points on the line. More...
 
std::vector< geometrize::ScanlinescanlinesForPolygon (const std::vector< std::pair< float, float > > &points)
 scanlinesForPolygon Gets the scanlines for a series of points that make up an arbitrary polygon. More...
 
std::vector< geometrize::Scanlinerasterize (const geometrize::Shape &s, std::int32_t xMin, std::int32_t yMin, std::int32_t xMax, std::int32_t yMax)
 
std::vector< geometrize::Scanlinerasterize (const geometrize::Circle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
std::vector< geometrize::Scanlinerasterize (const geometrize::Ellipse &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
std::vector< geometrize::Scanlinerasterize (const geometrize::Line &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
std::vector< geometrize::Scanlinerasterize (const geometrize::Polyline &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
std::vector< geometrize::Scanlinerasterize (const geometrize::QuadraticBezier &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
std::vector< geometrize::Scanlinerasterize (const geometrize::Rectangle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
std::vector< geometrize::Scanlinerasterize (const geometrize::RotatedEllipse &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
std::vector< geometrize::Scanlinerasterize (const geometrize::RotatedRectangle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
std::vector< geometrize::Scanlinerasterize (const geometrize::Triangle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
bool scanlinesOverlap (const std::vector< geometrize::Scanline > &first, const std::vector< geometrize::Scanline > &second)
 scanlinesOverlap Returns true if any of the scanlines from the first vector overlap the second More...
 
bool scanlinesContain (const std::vector< geometrize::Scanline > &first, const std::vector< geometrize::Scanline > &second)
 scanlinesContain Returns true if the first vector of scanlines wholly contain the second vector of scanlines. More...
 
bool shapesOverlap (const geometrize::Shape &a, const geometrize::Shape &b, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
bool shapeContains (const geometrize::Shape &container, const geometrize::Shape &containee, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
std::vector< std::pair< std::int32_t, std::int32_t > > shapeToPixels (const geometrize::Shape &shape, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
bool operator== (const geometrize::Scanline &lhs, const geometrize::Scanline &rhs)
 
bool operator!= (const geometrize::Scanline &lhs, const geometrize::Scanline &rhs)
 
std::vector< geometrize::ScanlinetrimScanlines (const std::vector< geometrize::Scanline > &scanlines, std::int32_t minX, std::int32_t minY, std::int32_t maxX, std::int32_t maxY)
 trimScanlines Crops the scanning width of an array of scanlines so they do not scan outside of the given area. More...
 
std::function< std::shared_ptr< geometrize::Shape >()> createDefaultShapeCreator (geometrize::ShapeTypes types, std::int32_t xMin, std::int32_t yMin, std::int32_t xMax, std::int32_t yMax)
 createDefaultShapeCreator Creates an instance of the default shape creator object. The setup, mutate and rasterize methods are bound with default methods. More...
 
std::shared_ptr< geometrize::Shapecreate (geometrize::ShapeTypes t)
 create Creates a new shape of the specified type. More...
 
std::shared_ptr< geometrize::ShaperandomShape ()
 randomShape Creates a random shape. More...
 
std::shared_ptr< geometrize::ShaperandomShapeOf (geometrize::ShapeTypes t)
 randomShapeOf Creates a random shape from the types supplied. More...
 
void setup (geometrize::Shape &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void setup (geometrize::Circle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void setup (geometrize::Ellipse &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void setup (geometrize::Line &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void setup (geometrize::Polyline &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void setup (geometrize::QuadraticBezier &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void setup (geometrize::Rectangle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void setup (geometrize::RotatedEllipse &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void setup (geometrize::RotatedRectangle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void setup (geometrize::Triangle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void mutate (geometrize::Shape &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void mutate (geometrize::Circle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void mutate (geometrize::Ellipse &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void mutate (geometrize::Line &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void mutate (geometrize::Polyline &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void mutate (geometrize::QuadraticBezier &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void mutate (geometrize::Rectangle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void mutate (geometrize::RotatedEllipse &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void mutate (geometrize::RotatedRectangle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void mutate (geometrize::Triangle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
 
void translate (geometrize::Shape &s, const float x, const float y)
 
void translate (geometrize::Circle &s, const float x, const float y)
 
void translate (geometrize::Ellipse &s, const float x, const float y)
 
void translate (geometrize::Line &s, const float x, const float y)
 
void translate (geometrize::Polyline &s, const float x, const float y)
 
void translate (geometrize::QuadraticBezier &s, const float x, const float y)
 
void translate (geometrize::Rectangle &s, const float x, const float y)
 
void translate (geometrize::RotatedEllipse &s, const float x, const float y)
 
void translate (geometrize::RotatedRectangle &s, const float x, const float y)
 
void translate (geometrize::Triangle &s, const float x, const float y)
 
void scale (geometrize::Shape &s, const float scaleFactor)
 
void scale (geometrize::Circle &s, const float scaleFactor)
 
void scale (geometrize::Ellipse &s, const float scaleFactor)
 
void scale (geometrize::Line &s, const float scaleFactor)
 
void scale (geometrize::Polyline &s, const float scaleFactor)
 
void scale (geometrize::QuadraticBezier &s, const float scaleFactor)
 
void scale (geometrize::Rectangle &s, const float scaleFactor)
 
void scale (geometrize::RotatedEllipse &s, const float scaleFactor)
 
void scale (geometrize::RotatedRectangle &s, const float scaleFactor)
 
void scale (geometrize::Triangle &s, const float scaleFactor)
 
void rotate (geometrize::Shape &s, const float angle)
 
void rotate (geometrize::Line &s, const float angle)
 
void rotate (geometrize::RotatedEllipse &s, const float angle)
 
void rotate (geometrize::RotatedRectangle &s, const float angle)
 
void rotate (geometrize::Triangle &s, const float angle)
 

Variables

const std::array< ShapeTypes, static_cast< std::size_t >(ShapeTypes::SHAPE_COUNT)> allShapes
 allShapes is a convenient array of all of the members of ShapeTypes. More...
 
const std::vector< std::pair< ShapeTypes, std::string > > shapeTypeNames
 shapeTypeNames provides a convenient mapping to names of types of shape (all lower case, underscores instead of spaces e.g. rotated_ellipse). More...
 

Typedef Documentation

◆ ShapeAcceptancePreconditionFunction

using geometrize::ShapeAcceptancePreconditionFunction = typedef std::function<bool( double lastScore, double newScore, const geometrize::Shape& shape, const std::vector<geometrize::Scanline>& lines, const geometrize::rgba& color, const geometrize::Bitmap& before, const geometrize::Bitmap& after, const geometrize::Bitmap& target)>

ShapeAcceptancePreconditionFunction Type alias for a function that is used to decide whether or not to finally add a shape to the image.

Parameters
lastScoreThe image similarity score prior to adding the shape
newScoreWhat the image similarity score would be after adding the shape
shapeThe shape that this function shall decide whether to add
linesThe scanlines for the pixels in the shape
colorThe colour of the shape
beforeThe image prior to adding the shape
afterThe image as it would be after adding the shape
targetThe image that we are trying to replicate
Returns
True to add the shape to the image, false not to

Enumeration Type Documentation

◆ ShapeTypes

enum geometrize::ShapeTypes : std::uint32_t

The ShapeTypes enum specifies the types of shapes that can be used. These can be combined to produce images composed of multiple primitive types.

Author
Sam Twidale (https://samcodes.co.uk/)
Enumerator
RECTANGLE 
ROTATED_RECTANGLE 
TRIANGLE 
ELLIPSE 
ROTATED_ELLIPSE 
CIRCLE 
LINE 
QUADRATIC_BEZIER 
POLYLINE 
SHAPE_COUNT 
17{
18 RECTANGLE = 1U,
20 TRIANGLE = 4U,
21 ELLIPSE = 8U,
22 ROTATED_ELLIPSE = 16U,
23 CIRCLE = 32U,
24 LINE = 64U,
25 QUADRATIC_BEZIER = 128U,
26 POLYLINE = 256U,
27 SHAPE_COUNT = 9U
28};
@ POLYLINE
Definition: shapetypes.h:26
@ ROTATED_RECTANGLE
Definition: shapetypes.h:19
@ CIRCLE
Definition: shapetypes.h:23
@ TRIANGLE
Definition: shapetypes.h:20
@ ELLIPSE
Definition: shapetypes.h:21
@ RECTANGLE
Definition: shapetypes.h:18
@ QUADRATIC_BEZIER
Definition: shapetypes.h:25
@ SHAPE_COUNT
Definition: shapetypes.h:27
@ LINE
Definition: shapetypes.h:24
@ ROTATED_ELLIPSE
Definition: shapetypes.h:22

Function Documentation

◆ bresenham()

std::vector< std::pair< std::int32_t, std::int32_t > > geometrize::bresenham ( std::int32_t  x1,
std::int32_t  y1,
std::int32_t  x2,
std::int32_t  y2 
)

bresenham Bresenham's line algorithm. Returns the points on the line.

Parameters
x1The start x-coordinate.
y1The start y-coordinate.
x2The end x-coordinate.
y2The end y-coordinate.
Returns
The points on the resulting line.
123{
124 std::int32_t dx{x2 - x1};
125 const std::int8_t ix{static_cast<std::int8_t>((dx > 0) - (dx < 0))};
126 dx = std::abs(dx) << 1;
127
128 std::int32_t dy{y2 - y1};
129 const std::int8_t iy{static_cast<std::int8_t>((dy > 0) - (dy < 0))};
130 dy = std::abs(dy) << 1;
131
132 std::vector<std::pair<std::int32_t, std::int32_t>> points;
133 points.push_back(std::make_pair(x1, y1));
134
135 if (dx >= dy) {
136 std::int32_t error(dy - (dx >> 1));
137 while (x1 != x2) {
138 if (error >= 0 && (error || (ix > 0))) {
139 error -= dx;
140 y1 += iy;
141 }
142
143 error += dy;
144 x1 += ix;
145
146 points.push_back(std::make_pair(x1, y1));
147 }
148 } else {
149 std::int32_t error(dx - (dy >> 1));
150 while (y1 != y2) {
151 if (error >= 0 && (error || (iy > 0))) {
152 error -= dy;
153 x1 += ix;
154 }
155
156 error += dx;
157 y1 += iy;
158
159 points.push_back(std::make_pair(x1, y1));
160 }
161 }
162
163 return points;
164}
Here is the caller graph for this function:

◆ copyLines()

void geometrize::copyLines ( geometrize::Bitmap destination,
const geometrize::Bitmap source,
const std::vector< geometrize::Scanline > &  lines 
)

copyLines Copies source pixels to a destination defined by a set of scanlines.

Parameters
destinationThe destination bitmap to copy the lines to.
sourceThe source bitmap to copy the lines from.
linesThe scanlines that comprise the source to destination copying mask.
113{
114 for(const geometrize::Scanline& line : lines) {
115 const std::int32_t y{line.y};
116 for(std::int32_t x = line.x1; x <= line.x2; x++) {
117 destination.setPixel(x, y, source.getPixel(x, y));
118 }
119 }
120}
void setPixel(std::uint32_t x, std::uint32_t y, geometrize::rgba color)
setPixel Sets a pixel color value.
Definition: bitmap.cpp:46
geometrize::rgba getPixel(std::uint32_t x, std::uint32_t y) const
getPixel Gets a pixel color value.
Definition: bitmap.cpp:40
The Scanline class represents a scanline, a row of pixels running across a bitmap.
Definition: scanline.h:14
Here is the call graph for this function:
Here is the caller graph for this function:

◆ create()

std::shared_ptr< geometrize::Shape > geometrize::create ( geometrize::ShapeTypes  t)

create Creates a new shape of the specified type.

Parameters
tThe type of shape to create.
Returns
The new shape.
96{
97 switch(t) {
99 return std::make_shared<geometrize::Polyline>();
101 return std::make_shared<geometrize::QuadraticBezier>();
103 return std::make_shared<geometrize::Circle>();
105 return std::make_shared<geometrize::Ellipse>();
107 return std::make_shared<geometrize::RotatedEllipse>();
109 return std::make_shared<geometrize::RotatedRectangle>();
111 return std::make_shared<geometrize::Triangle>();
113 return std::make_shared<geometrize::Rectangle>();
115 return std::make_shared<geometrize::Line>();
116 default:
117 assert(0 && "Bad shape type specified");
118 };
119
120 assert(0 && "Unhandled shape type encountered");
121 return std::make_shared<geometrize::Rectangle>();
122}
Here is the caller graph for this function:

◆ createDefaultShapeCreator()

std::function< std::shared_ptr< geometrize::Shape >()> geometrize::createDefaultShapeCreator ( geometrize::ShapeTypes  types,
std::int32_t  xMin,
std::int32_t  yMin,
std::int32_t  xMax,
std::int32_t  yMax 
)

createDefaultShapeCreator Creates an instance of the default shape creator object. The setup, mutate and rasterize methods are bound with default methods.

Parameters
typesThe types of shapes to create.
xMinThe minimum x coordinate of the shapes created.
yMinThe minimum y coordinate of the shapes created.
xMaxThe maximum x coordinate of the shapes created.
yMaxThe maximum y coordinate of the shapes created.
Returns
The default shape creator.
26{
27 auto f = [types, xMin, yMin, xMax, yMax]() {
28 std::shared_ptr<geometrize::Shape> s = geometrize::randomShapeOf(types);
29
30 switch(s->getType()) {
32 s->setup = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { return geometrize::setup(static_cast<geometrize::Rectangle&>(s), xMin, yMin, xMax, yMax); };
33 s->mutate = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { geometrize::mutate(static_cast<geometrize::Rectangle&>(s), xMin, yMin, xMax, yMax); };
34 s->rasterize = [xMin, yMin, xMax, yMax](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::Rectangle&>(s), xMin, yMin, xMax, yMax); };
35 break;
36 }
38 s->setup = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { return geometrize::setup(static_cast<geometrize::RotatedRectangle&>(s), xMin, yMin, xMax, yMax); };
39 s->mutate = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { geometrize::mutate(static_cast<geometrize::RotatedRectangle&>(s), xMin, yMin, xMax, yMax); };
40 s->rasterize = [xMin, yMin, xMax, yMax](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::RotatedRectangle&>(s), xMin, yMin, xMax, yMax); };
41 break;
42 }
44 s->setup = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { return geometrize::setup(static_cast<geometrize::Triangle&>(s), xMin, yMin, xMax, yMax); };
45 s->mutate = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { geometrize::mutate(static_cast<geometrize::Triangle&>(s), xMin, yMin, xMax, yMax); };
46 s->rasterize = [xMin, yMin, xMax, yMax](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::Triangle&>(s), xMin, yMin, xMax, yMax); };
47 break;
48 }
50 s->setup = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { return geometrize::setup(static_cast<geometrize::Ellipse&>(s), xMin, yMin, xMax, yMax); };
51 s->mutate = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { geometrize::mutate(static_cast<geometrize::Ellipse&>(s), xMin, yMin, xMax, yMax); };
52 s->rasterize = [xMin, yMin, xMax, yMax](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::Ellipse&>(s), xMin, yMin, xMax, yMax); };
53 break;
54 }
56 s->setup = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { return geometrize::setup(static_cast<geometrize::RotatedEllipse&>(s), xMin, yMin, xMax, yMax); };
57 s->mutate = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { geometrize::mutate(static_cast<geometrize::RotatedEllipse&>(s), xMin, yMin, xMax, yMax); };
58 s->rasterize = [xMin, yMin, xMax, yMax](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::RotatedEllipse&>(s), xMin, yMin, xMax, yMax); };
59 break;
60 }
62 s->setup = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { return geometrize::setup(static_cast<geometrize::Circle&>(s), xMin, yMin, xMax, yMax); };
63 s->mutate = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { geometrize::mutate(static_cast<geometrize::Circle&>(s), xMin, yMin, xMax, yMax); };
64 s->rasterize = [xMin, yMin, xMax, yMax](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::Circle&>(s), xMin, yMin, xMax, yMax); };
65 break;
66 }
68 s->setup = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { return geometrize::setup(static_cast<geometrize::Line&>(s), xMin, yMin, xMax, yMax); };
69 s->mutate = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { geometrize::mutate(static_cast<geometrize::Line&>(s), xMin, yMin, xMax, yMax); };
70 s->rasterize = [xMin, yMin, xMax, yMax](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::Line&>(s), xMin, yMin, xMax, yMax); };
71 break;
72 }
74 s->setup = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { return geometrize::setup(static_cast<geometrize::QuadraticBezier&>(s), xMin, yMin, xMax, yMax); };
75 s->mutate = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { geometrize::mutate(static_cast<geometrize::QuadraticBezier&>(s), xMin, yMin, xMax, yMax); };
76 s->rasterize = [xMin, yMin, xMax, yMax](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::QuadraticBezier&>(s), xMin, yMin, xMax, yMax); };
77 break;
78 }
80 s->setup = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { return geometrize::setup(static_cast<geometrize::Polyline&>(s), xMin, yMin, xMax, yMax); };
81 s->mutate = [xMin, yMin, xMax, yMax](geometrize::Shape& s) { geometrize::mutate(static_cast<geometrize::Polyline&>(s), xMin, yMin, xMax, yMax); };
82 s->rasterize = [xMin, yMin, xMax, yMax](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::Polyline&>(s), xMin, yMin, xMax, yMax); };
83 break;
84 }
85 default:
86 assert(0 && "Bad shape type");
87 }
88
89 return s;
90 };
91
92 return f;
93}
The Circle class represents a circle.
Definition: circle.h:16
The Ellipse class represents an ellipse.
Definition: ellipse.h:16
The Line class represents a simple line.
Definition: line.h:16
The Polyline class represents a polyline.
Definition: polyline.h:18
The QuadraticBezier class represents a quadratic bezier curve.
Definition: quadraticbezier.h:16
The Rectangle class represents a rectangle.
Definition: rectangle.h:16
The RotatedEllipse class represents a rotated ellipse.
Definition: rotatedellipse.h:16
The RotatedRectangle class represents a rotated rectangle.
Definition: rotatedrectangle.h:16
Definition: shape.h:18
The Triangle class represents a triangle.
Definition: triangle.h:16
std::shared_ptr< geometrize::Shape > randomShapeOf(const ShapeTypes types)
randomShapeOf Creates a random shape from the types supplied.
Definition: shapefactory.cpp:129
std::vector< geometrize::Scanline > rasterize(const geometrize::Shape &s, std::int32_t xMin, std::int32_t yMin, std::int32_t xMax, std::int32_t yMax)
Definition: rasterizer.cpp:194
void mutate(geometrize::Shape &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
Definition: shapemutator.cpp:155
void setup(geometrize::Shape &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
Definition: shapemutator.cpp:37
Here is the call graph for this function:
Here is the caller graph for this function:

◆ drawLines()

void geometrize::drawLines ( geometrize::Bitmap image,
geometrize::rgba  color,
const std::vector< geometrize::Scanline > &  lines 
)

drawLines Draws scanlines onto an image.

Parameters
imageThe image to be drawn to.
colorThe color of the scanlines.
linesThe scanlines to draw.
75{
76 // Convert the non-premultiplied color to alpha-premultiplied 16-bits per channel RGBA
77 // In other words, scale the rgb color components by the alpha component
78 std::uint32_t sr{color.r};
79 sr |= sr << 8;
80 sr *= color.a;
81 sr /= UINT8_MAX;
82 std::uint32_t sg{color.g};
83 sg |= sg << 8;
84 sg *= color.a;
85 sg /= UINT8_MAX;
86 std::uint32_t sb{color.b};
87 sb |= sb << 8;
88 sb *= color.a;
89 sb /= UINT8_MAX;
90 std::uint32_t sa{color.a};
91 sa |= sa << 8;
92
93 const std::uint32_t m{UINT16_MAX};
94 const std::uint32_t aa{(m - sa) * 257U};
95
96 for(const geometrize::Scanline& line : lines) {
97 const std::int32_t y{line.y};
98
99 for(std::int32_t x = line.x1; x <= line.x2; x++) {
100 const geometrize::rgba d(image.getPixel(x, y));
101
102 const std::uint8_t r{static_cast<std::uint8_t>(((d.r * aa + sr * m) / m) >> 8)};
103 const std::uint8_t g{static_cast<std::uint8_t>(((d.g * aa + sg * m) / m) >> 8)};
104 const std::uint8_t b{static_cast<std::uint8_t>(((d.b * aa + sb * m) / m) >> 8)};
105 const std::uint8_t a{static_cast<std::uint8_t>(((d.a * aa + sa * m) / m) >> 8)};
106
107 image.setPixel(x, y, geometrize::rgba{r, g, b, a});
108 }
109 }
110}
The rgba struct is a helper for manipulating RGBA8888 color data.
Definition: rgba.h:13
std::uint8_t a
‍The blue component (0-255).
Definition: rgba.h:17
std::uint8_t g
‍The red component (0-255).
Definition: rgba.h:15
std::uint8_t r
Definition: rgba.h:14
std::uint8_t b
‍The green component (0-255).
Definition: rgba.h:16
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCornerPoints()

std::vector< std::pair< float, float > > geometrize::getCornerPoints ( const geometrize::RotatedRectangle r)

getCornerPoints Gets the corner points of the given rotated rectangle.

Parameters
rThe rotated rectangle.
Returns
The corner points of the rotated rectangle.
31{
32 const float x1{(std::fmin)(r.m_x1, r.m_x2)};
33 const float x2{(std::fmax)(r.m_x1, r.m_x2)};
34 const float y1{(std::fmin)(r.m_y1, r.m_y2)};
35 const float y2{(std::fmax)(r.m_y1, r.m_y2)};
36
37 const float cx{(x2 + x1) / 2.0f};
38 const float cy{(y2 + y1) / 2.0f};
39
40 const float ox1{x1 - cx};
41 const float ox2{x2 - cx};
42 const float oy1{y1 - cy};
43 const float oy2{y2 - cy};
44
45 const float rads{r.m_angle * 3.141f / 180.0f};
46 const float c{std::cos(rads)};
47 const float s{std::sin(rads)};
48
49 const std::pair<float, float> ul{ox1 * c - oy1 * s + cx, ox1 * s + oy1 * c + cy};
50 const std::pair<float, float> bl{ox1 * c - oy2 * s + cx, ox1 * s + oy2 * c + cy};
51 const std::pair<float, float> ur{ox2 * c - oy1 * s + cx, ox2 * s + oy1 * c + cy};
52 const std::pair<float, float> br{ox2 * c - oy2 * s + cx, ox2 * s + oy2 * c + cy};
53
54 return {ul, ur, br, bl};
55}
float m_y1
Top coordinate.
Definition: rotatedrectangle.h:25
float m_y2
Bottom coordinate.
Definition: rotatedrectangle.h:27
float m_x1
Left coordinate.
Definition: rotatedrectangle.h:24
float m_x2
Right coordinate.
Definition: rotatedrectangle.h:26
float m_angle
Rotation angle.
Definition: rotatedrectangle.h:28
Here is the caller graph for this function:

◆ getPointsOnRotatedEllipse()

std::vector< std::pair< float, float > > geometrize::getPointsOnRotatedEllipse ( const geometrize::RotatedEllipse e,
std::size_t  numPoints 
)

getPointsOnRotatedEllipse Calculates and returns a number of points on the given rotated ellipse.

Parameters
eThe rotated ellipse.
Returns
A vector containing the points on the rotated ellipse.
58{
59 std::vector<std::pair<float, float>> points;
60 const float rads{e.m_angle * (3.141f / 180.0f)};
61 const float co{std::cos(rads)};
62 const float si{std::sin(rads)};
63
64 for(std::uint32_t i = 0; i < numPoints; i++) {
65 const float angle{((360.0f / numPoints) * i) * (3.141f / 180.0f)};
66 const float crx{e.m_rx * std::cos(angle)};
67 const float cry{e.m_ry * std::sin(angle)};
68 points.push_back(std::make_pair(crx * co - cry * si + e.m_x, crx * si + cry * co + e.m_y));
69 }
70
71 return points;
72}
float m_rx
x-radius.
Definition: rotatedellipse.h:26
float m_y
y-coordinate.
Definition: rotatedellipse.h:25
float m_angle
Rotation angle.
Definition: rotatedellipse.h:28
float m_x
x-coordinate.
Definition: rotatedellipse.h:24
float m_ry
y-radius.
Definition: rotatedellipse.h:27
Here is the caller graph for this function:

◆ getRawShapeData() [1/10]

std::vector< float > geometrize::getRawShapeData ( const geometrize::Circle s)
49{
50 return { s.m_x, s.m_y, s.m_r };
51}
float m_r
Radius.
Definition: circle.h:26
float m_y
y-coordinate.
Definition: circle.h:25
float m_x
x-coordinate.
Definition: circle.h:24

◆ getRawShapeData() [2/10]

std::vector< float > geometrize::getRawShapeData ( const geometrize::Ellipse s)
54{
55 return { s.m_x, s.m_y, s.m_rx, s.m_ry };
56}
float m_rx
x-radius.
Definition: ellipse.h:26
float m_y
y-coordinate.
Definition: ellipse.h:25
float m_ry
y-radius.
Definition: ellipse.h:27
float m_x
x-coordinate.
Definition: ellipse.h:24

◆ getRawShapeData() [3/10]

std::vector< float > geometrize::getRawShapeData ( const geometrize::Line s)
59{
60 return { s.m_x1, s.m_y1, s.m_x2, s.m_y2 };
61}
float m_y1
First y-coordinate.
Definition: line.h:25
float m_y2
Second y-coordinate.
Definition: line.h:27
float m_x2
Second x-coordinate.
Definition: line.h:26
float m_x1
First x-coordinate.
Definition: line.h:24

◆ getRawShapeData() [4/10]

std::vector< float > geometrize::getRawShapeData ( const geometrize::Polyline s)
64{
65 std::vector<float> data;
66 for(std::size_t i = 0; i < s.m_points.size(); i++) {
67 data.push_back(s.m_points[i].first);
68 data.push_back(s.m_points[i].second);
69 }
70
71 return data;
72}
std::vector< std::pair< float, float > > m_points
The points on the polyline.
Definition: polyline.h:26

◆ getRawShapeData() [5/10]

std::vector< float > geometrize::getRawShapeData ( const geometrize::QuadraticBezier s)
75{
76 return { s.m_x1, s.m_y1, s.m_cx, s.m_cy, s.m_x2, s.m_y2 };
77}
float m_x1
First x-coordinate.
Definition: quadraticbezier.h:26
float m_y2
Second y-coordinate.
Definition: quadraticbezier.h:29
float m_cy
Control point y-coordinate.
Definition: quadraticbezier.h:25
float m_cx
Control point x-coordinate.
Definition: quadraticbezier.h:24
float m_x2
Second x-coordinate.
Definition: quadraticbezier.h:28
float m_y1
First y-coordinate.
Definition: quadraticbezier.h:27

◆ getRawShapeData() [6/10]

std::vector< float > geometrize::getRawShapeData ( const geometrize::Rectangle s)
80{
81 return {
82 ((std::fmin)(s.m_x1, s.m_x2)),
83 ((std::fmin)(s.m_y1, s.m_y2)),
84 ((std::fmax)(s.m_x1, s.m_x2)),
85 ((std::fmax)(s.m_y1, s.m_y2))
86 };
87}
float m_y1
Top coordinate.
Definition: rectangle.h:25
float m_x2
Right coordinate.
Definition: rectangle.h:26
float m_y2
Bottom coordinate.
Definition: rectangle.h:27
float m_x1
Left coordinate.
Definition: rectangle.h:24

◆ getRawShapeData() [7/10]

std::vector< float > geometrize::getRawShapeData ( const geometrize::RotatedEllipse s)
90{
91 return { s.m_x, s.m_y, s.m_rx, s.m_ry, s.m_angle };
92}

◆ getRawShapeData() [8/10]

std::vector< float > geometrize::getRawShapeData ( const geometrize::RotatedRectangle s)
95{
96 return {
97 ((std::fmin)(s.m_x1, s.m_x2)),
98 ((std::fmin)(s.m_y1, s.m_y2)),
99 ((std::fmax)(s.m_x1, s.m_x2)),
100 ((std::fmax)(s.m_y1, s.m_y2)),
101 s.m_angle
102 };
103}

◆ getRawShapeData() [9/10]

std::vector< float > geometrize::getRawShapeData ( const geometrize::Shape s)
22{
23 switch(s.getType()) {
25 return getRawShapeData(static_cast<const geometrize::Rectangle&>(s));
27 return getRawShapeData(static_cast<const geometrize::RotatedRectangle&>(s));
29 return getRawShapeData(static_cast<const geometrize::Triangle&>(s));
31 return getRawShapeData(static_cast<const geometrize::Ellipse&>(s));
33 return getRawShapeData(static_cast<const geometrize::RotatedEllipse&>(s));
35 return getRawShapeData(static_cast<const geometrize::Circle&>(s));
37 return getRawShapeData(static_cast<const geometrize::Line&>(s));
39 return getRawShapeData(static_cast<const geometrize::QuadraticBezier&>(s));
41 return getRawShapeData(static_cast<const geometrize::Polyline&>(s));
42 default:
43 assert(0 && "Bad shape type");
44 return {};
45 }
46}
virtual geometrize::ShapeTypes getType() const
getType Gets the ShapeType of the shape.
Definition: shape.h:42
std::vector< float > getRawShapeData(const geometrize::Triangle &s)
Definition: shapeserializer.cpp:105
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getRawShapeData() [10/10]

std::vector< float > geometrize::getRawShapeData ( const geometrize::Triangle s)
106{
107 return { s.m_x1, s.m_y1, s.m_x2, s.m_y2, s.m_x3, s.m_y3 };
108}
float m_x3
Third x-coordinate.
Definition: triangle.h:28
float m_y3
Third y-coordinate.
Definition: triangle.h:29
float m_y1
First y-coordinate.
Definition: triangle.h:25
float m_x2
Second x-coordinate.
Definition: triangle.h:26
float m_x1
First x-coordinate.
Definition: triangle.h:24
float m_y2
Second y-coordinate.
Definition: triangle.h:27

◆ mutate() [1/10]

void geometrize::mutate ( geometrize::Circle s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
191{
192 const std::int32_t r{geometrize::commonutil::randomRange(0, 1)};
193 switch(r) {
194 case 0:
195 {
196 s.m_x = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x) + geometrize::commonutil::randomRange(-16, 16), xMin, xMax - 1);
197 s.m_y = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y) + geometrize::commonutil::randomRange(-16, 16), yMin, yMax - 1);
198 break;
199 }
200 case 1:
201 {
202 s.m_r = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_r) + geometrize::commonutil::randomRange(-16, 16), 1, xMax - 1);
203 break;
204 }
205 }
206}
std::int32_t randomRange(const std::int32_t min, const std::int32_t max)
randomRange Returns a random integer in the range, inclusive. Uses thread-local random number generat...
Definition: commonutil.cpp:29
T clamp(const T &value, const T &lower, const T &upper)
clamp Clamps a value within a range.
Definition: commonutil.h:45
Here is the call graph for this function:

◆ mutate() [2/10]

void geometrize::mutate ( geometrize::Ellipse s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
209{
210 const std::int32_t r{geometrize::commonutil::randomRange(0, 2)};
211 switch(r) {
212 case 0:
213 {
214 s.m_x = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x) + geometrize::commonutil::randomRange(-16, 16), xMin, xMax - 1);
215 s.m_y = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y) + geometrize::commonutil::randomRange(-16, 16), yMin, yMax - 1);
216 break;
217 }
218 case 1:
219 {
220 s.m_rx = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_rx) + geometrize::commonutil::randomRange(-16, 16), 1, xMax - 1);
221 break;
222 }
223 case 2:
224 {
225 s.m_ry = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_ry) + geometrize::commonutil::randomRange(-16, 16), 1, yMax - 1);
226 break;
227 }
228 }
229}
Here is the call graph for this function:

◆ mutate() [3/10]

void geometrize::mutate ( geometrize::Line s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
232{
233 const std::int32_t r{geometrize::commonutil::randomRange(0, 1)};
234
235 switch(r) {
236 case 0:
237 {
238 s.m_x1 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x1) + geometrize::commonutil::randomRange(-16, 16), xMin, xMax - 1);
239 s.m_y1 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y1) + geometrize::commonutil::randomRange(-16, 16), yMin, yMax - 1);
240 break;
241 }
242 case 1:
243 {
244 s.m_x2 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x2) + geometrize::commonutil::randomRange(-16, 16), xMin, xMax - 1);
245 s.m_y2 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y2) + geometrize::commonutil::randomRange(-16, 16), yMin, yMax - 1);
246 break;
247 }
248 }
249}
Here is the call graph for this function:

◆ mutate() [4/10]

void geometrize::mutate ( geometrize::Polyline s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
252{
253 const std::int32_t i{geometrize::commonutil::randomRange(static_cast<std::size_t>(0), s.m_points.size() - 1)};
254
255 std::pair<std::int32_t, std::int32_t> point{s.m_points[i]};
256 point.first = geometrize::commonutil::clamp(point.first + geometrize::commonutil::randomRange(-64, 64), xMin, xMax - 1);
257 point.second = geometrize::commonutil::clamp(point.second + geometrize::commonutil::randomRange(-64, 64), yMin, yMax - 1);
258
259 s.m_points[i] = point;
260}
Here is the call graph for this function:

◆ mutate() [5/10]

void geometrize::mutate ( geometrize::QuadraticBezier s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
263{
264 const std::int32_t r{geometrize::commonutil::randomRange(0, 2)};
265 switch(r) {
266 case 0:
267 {
268 s.m_cx = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_cx) + geometrize::commonutil::randomRange(-8, 8), xMin, xMax - 1);
269 s.m_cy = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_cy) + geometrize::commonutil::randomRange(-8, 8), yMin, yMax - 1);
270 break;
271 }
272 case 1:
273 {
274 // NOTE +1 on the minimum values for paranoia reasons as I wrote it that way originally, not sure if it's needed
275 s.m_x1 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x1) + geometrize::commonutil::randomRange(-8, 8), xMin + 1, xMax - 1);
276 s.m_y1 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y1) + geometrize::commonutil::randomRange(-8, 8), yMin + 1, yMax - 1);
277 break;
278 }
279 case 2:
280 {
281 // NOTE +1 on the minimum values for paranoia reasons as I wrote it that way originally, not sure if it's needed
282 s.m_x2 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x2) + geometrize::commonutil::randomRange(-8, 8), xMin + 1, xMax - 1);
283 s.m_y2 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y2) + geometrize::commonutil::randomRange(-8, 8), yMin + 1, yMax - 1);
284 break;
285 }
286 }
287}
Here is the call graph for this function:

◆ mutate() [6/10]

void geometrize::mutate ( geometrize::Rectangle s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
290{
291 const std::int32_t r{geometrize::commonutil::randomRange(0, 1)};
292 switch(r) {
293 case 0:
294 {
295 s.m_x1 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x1) + geometrize::commonutil::randomRange(-16, 16), xMin, xMax - 1);
296 s.m_y1 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y1) + geometrize::commonutil::randomRange(-16, 16), yMin, yMax - 1);
297 break;
298 }
299 case 1:
300 {
301 s.m_x2 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x2) + geometrize::commonutil::randomRange(-16, 16), xMin, xMax - 1);
302 s.m_y2 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y2) + geometrize::commonutil::randomRange(-16, 16), yMin, yMax - 1);
303 break;
304 }
305 }
306}
Here is the call graph for this function:

◆ mutate() [7/10]

void geometrize::mutate ( geometrize::RotatedEllipse s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
309{
310 const std::int32_t r{geometrize::commonutil::randomRange(0, 3)};
311 switch(r) {
312 case 0:
313 {
314 s.m_x = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x) + geometrize::commonutil::randomRange(-16, 16), xMin, xMax - 1);
315 s.m_y = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y) + geometrize::commonutil::randomRange(-16, 16), yMin, yMax - 1);
316 break;
317 }
318 case 1:
319 {
320 s.m_rx = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_rx) + geometrize::commonutil::randomRange(-16, 16), 1, xMax - 1);
321 break;
322 }
323 case 2:
324 {
325 s.m_ry = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_ry) + geometrize::commonutil::randomRange(-16, 16), 1, yMax - 1);
326 break;
327 }
328 case 3:
329 {
330 s.m_angle = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_angle) + geometrize::commonutil::randomRange(-16, 16), 0, 360);
331 break;
332 }
333 }
334}
Here is the call graph for this function:

◆ mutate() [8/10]

void geometrize::mutate ( geometrize::RotatedRectangle s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
337{
338 const std::int32_t r{geometrize::commonutil::randomRange(0, 2)};
339 switch(r) {
340 case 0:
341 {
342 s.m_x1 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x1) + geometrize::commonutil::randomRange(-16, 16), xMin, xMax);
343 s.m_y1 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y1) + geometrize::commonutil::randomRange(-16, 16), yMin, yMax);
344 break;
345 }
346 case 1:
347 {
348 s.m_x2 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x2) + geometrize::commonutil::randomRange(-16, 16), xMin, xMax);
349 s.m_y2 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y2) + geometrize::commonutil::randomRange(-16, 16), yMin, yMax);
350 break;
351 }
352 case 2:
353 {
354 s.m_angle = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_angle) + geometrize::commonutil::randomRange(-4, 4), 0, 360);
355 break;
356 }
357 }
358}
Here is the call graph for this function:

◆ mutate() [9/10]

void geometrize::mutate ( geometrize::Shape s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
156{
157 switch(s.getType()) {
159 mutate(static_cast<geometrize::Rectangle&>(s), xMin, yMin, xMax, yMax);
160 break;
162 mutate(static_cast<geometrize::RotatedRectangle&>(s), xMin, yMin, xMax, yMax);
163 break;
165 mutate(static_cast<geometrize::Triangle&>(s), xMin, yMin, xMax, yMax);
166 break;
168 mutate(static_cast<geometrize::Ellipse&>(s), xMin, yMin, xMax, yMax);
169 break;
171 mutate(static_cast<geometrize::RotatedEllipse&>(s), xMin, yMin, xMax, yMax);
172 break;
174 mutate(static_cast<geometrize::Circle&>(s), xMin, yMin, xMax, yMax);
175 break;
177 mutate(static_cast<geometrize::Line&>(s), xMin, yMin, xMax, yMax);
178 break;
180 mutate(static_cast<geometrize::QuadraticBezier&>(s), xMin, yMin, xMax, yMax);
181 break;
183 mutate(static_cast<geometrize::Polyline&>(s), xMin, yMin, xMax, yMax);
184 break;
185 default:
186 assert(0 && "Bad shape type");
187 }
188}
void mutate(geometrize::Triangle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
Definition: shapemutator.cpp:360
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mutate() [10/10]

void geometrize::mutate ( geometrize::Triangle s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
361{
362 const std::int32_t r{geometrize::commonutil::randomRange(0, 2)};
363 switch(r) {
364 case 0:
365 {
366 s.m_x1 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x1) + geometrize::commonutil::randomRange(-32, 32), xMin, xMax);
367 s.m_y1 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y1) + geometrize::commonutil::randomRange(-32, 32), yMin, yMax);
368 break;
369 }
370 case 1:
371 {
372 s.m_x2 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x2) + geometrize::commonutil::randomRange(-32, 32), xMin, xMax);
373 s.m_y2 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y2) + geometrize::commonutil::randomRange(-32, 32), yMin, yMax);
374 break;
375 }
376 case 2:
377 {
378 s.m_x3 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x3) + geometrize::commonutil::randomRange(-32, 32), xMin, xMax);
379 s.m_y3 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y3) + geometrize::commonutil::randomRange(-32, 32), yMin, yMax);
380 break;
381 }
382 }
383}
Here is the call graph for this function:

◆ operator!=() [1/2]

bool geometrize::operator!= ( const geometrize::rgba lhs,
const geometrize::rgba rhs 
)
12{
13 return lhs.r != rhs.r || lhs.g != rhs.g || lhs.b != rhs.b || lhs.a != rhs.a;
14}

◆ operator!=() [2/2]

bool geometrize::operator!= ( const geometrize::Scanline lhs,
const geometrize::Scanline rhs 
)
19{
20 return lhs.y != rhs.y || lhs.x1 != rhs.x1 || lhs.x2 != rhs.x2;
21}
std::int32_t x2
The rightmost x-coordinate of the scanline.
Definition: scanline.h:35
std::int32_t y
The y-coordinate of the scanline.
Definition: scanline.h:33
std::int32_t x1
The leftmost x-coordinate of the scanline.
Definition: scanline.h:34

◆ operator==() [1/2]

bool geometrize::operator== ( const geometrize::rgba lhs,
const geometrize::rgba rhs 
)
7{
8 return lhs.r == rhs.r && lhs.g == rhs.g && lhs.b == rhs.b && lhs.a == rhs.a;
9}

◆ operator==() [2/2]

bool geometrize::operator== ( const geometrize::Scanline lhs,
const geometrize::Scanline rhs 
)
14{
15 return lhs.y == rhs.y && lhs.x1 == rhs.x1 && lhs.x2 == rhs.x2;
16}

◆ randomShape()

std::shared_ptr< geometrize::Shape > geometrize::randomShape ( )

randomShape Creates a random shape.

Returns
The new shape.
125{
126 return create(geometrize::allShapes[commonutil::randomRange(0, static_cast<int>(geometrize::allShapes.size()) - 1)]);
127}
const std::array< ShapeTypes, static_cast< std::size_t >(ShapeTypes::SHAPE_COUNT)> allShapes
allShapes is a convenient array of all of the members of ShapeTypes.
Definition: shapetypes.cpp:6
std::shared_ptr< geometrize::Shape > create(const geometrize::ShapeTypes t)
create Creates a new shape of the specified type.
Definition: shapefactory.cpp:95
Here is the call graph for this function:
Here is the caller graph for this function:

◆ randomShapeOf()

std::shared_ptr< geometrize::Shape > geometrize::randomShapeOf ( geometrize::ShapeTypes  t)

randomShapeOf Creates a random shape from the types supplied.

Parameters
tThe types of shape to possibly create.
Returns
The new shape.
130{
131 std::vector<ShapeTypes> typeVector;
132 for(const ShapeTypes type : geometrize::allShapes) {
133 if((type & types) == type) {
134 typeVector.push_back(type);
135 }
136 }
137
138 if(typeVector.size() == 0) {
139 return randomShape(); // If there are no types specified, create one randomly
140 }
141
142 return create(typeVector.at(commonutil::randomRange(0, static_cast<std::int32_t>(typeVector.size() - 1))));
143}
ShapeTypes
The ShapeTypes enum specifies the types of shapes that can be used. These can be combined to produce ...
Definition: shapetypes.h:17
std::shared_ptr< geometrize::Shape > randomShape()
randomShape Creates a random shape.
Definition: shapefactory.cpp:124
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rasterize() [1/10]

std::vector< geometrize::Scanline > geometrize::rasterize ( const geometrize::Circle s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
222{
223 std::vector<geometrize::Scanline> lines;
224
225 const std::int32_t r{static_cast<std::int32_t>(s.m_r)};
226 for(std::int32_t y = -r; y <= r; y++) {
227 std::vector<std::int32_t> xScan;
228 for(std::int32_t x = -r; x <= r; x++) {
229 if(x * x + y * y <= r * r) {
230 xScan.push_back(x);
231 }
232 }
233
234 if(!xScan.empty()) {
235 const std::int32_t fy{static_cast<std::int32_t>(s.m_y) + y};
236 const std::int32_t x1{commonutil::clamp(static_cast<std::int32_t>(s.m_x) + xScan.front(), xMin, xMax - 1)};
237 const std::int32_t x2{commonutil::clamp(static_cast<std::int32_t>(s.m_x) + xScan.back(), xMin, xMax - 1)};
238 lines.push_back(geometrize::Scanline(fy, x1, x2));
239 }
240 }
241
242 return geometrize::trimScanlines(lines, xMin, yMin, xMax, yMax);
243}
std::vector< geometrize::Scanline > trimScanlines(const std::vector< geometrize::Scanline > &scanlines, std::int32_t minX, std::int32_t minY, std::int32_t maxX, std::int32_t maxY)
trimScanlines Crops the scanning width of an array of scanlines so they do not scan outside of the gi...
Definition: scanline.cpp:23
Here is the call graph for this function:

◆ rasterize() [2/10]

std::vector< geometrize::Scanline > geometrize::rasterize ( const geometrize::Ellipse s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
246{
247 std::vector<geometrize::Scanline> lines;
248
249 const float aspect{static_cast<float>(s.m_rx) / static_cast<float>(s.m_ry)};
250
251 for (std::int32_t dy = 0; dy < s.m_ry; dy++) {
252 const std::int32_t y1{static_cast<std::int32_t>(s.m_y) - dy};
253 const std::int32_t y2{static_cast<std::int32_t>(s.m_y) + dy};
254
255 if ((y1 < yMin || y1 >= yMax) && (y2 < yMin || y2 >= yMax)) {
256 continue;
257 }
258
259 const std::int32_t v{static_cast<std::int32_t>(std::sqrt(s.m_ry * s.m_ry - dy * dy) * aspect)};
260 std::int32_t x1{static_cast<std::int32_t>(s.m_x) - v};
261 std::int32_t x2{static_cast<std::int32_t>(s.m_x) + v};
262 if (x1 < xMin) {
263 x1 = xMin;
264 }
265 if (x2 >= xMax) {
266 x2 = xMax - 1;
267 }
268
269 if (y1 >= xMin && y1 < yMax) {
270 lines.push_back(Scanline(y1, x1, x2));
271 }
272 if (y2 >= yMin && y2 < yMax && dy > 0) {
273 lines.push_back(Scanline(y2, x1, x2));
274 }
275 }
276
277 return geometrize::trimScanlines(lines, xMin, yMin, xMax, yMax);
278}
Here is the call graph for this function:

◆ rasterize() [3/10]

std::vector< geometrize::Scanline > geometrize::rasterize ( const geometrize::Line s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
281{
282 std::vector<geometrize::Scanline> lines;
283
284 const std::vector<std::pair<std::int32_t, std::int32_t>> points{geometrize::bresenham(static_cast<std::int32_t>(s.m_x1), static_cast<std::int32_t>(s.m_y1), static_cast<std::int32_t>(s.m_x2), static_cast<std::int32_t>(s.m_y2))};
285 for(const auto& point : points) {
286 lines.push_back(geometrize::Scanline(point.second, point.first, point.first));
287 }
288
289 return geometrize::trimScanlines(lines, xMin, yMin, xMax, yMax);
290}
std::vector< std::pair< std::int32_t, std::int32_t > > bresenham(std::int32_t x1, std::int32_t y1, const std::int32_t x2, const std::int32_t y2)
bresenham Bresenham's line algorithm. Returns the points on the line.
Definition: rasterizer.cpp:122
Here is the call graph for this function:

◆ rasterize() [4/10]

std::vector< geometrize::Scanline > geometrize::rasterize ( const geometrize::Polyline s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
293{
294 std::vector<geometrize::Scanline> lines;
295
296 // Prevent scanline overlap, it messes up the energy functions that rely on the scanlines not intersecting themselves
297 std::set<std::pair<std::int32_t, std::int32_t>> duplicates;
298
299 for(std::size_t i = 0; i < s.m_points.size(); i++) {
300 const std::pair<std::int32_t, std::int32_t> p0{s.m_points[i].first, s.m_points[i].second};
301 const std::pair<std::int32_t, std::int32_t> p1{i < (s.m_points.size() - 1) ? std::make_pair(static_cast<std::int32_t>(s.m_points[i + 1].first), static_cast<std::int32_t>(s.m_points[i + 1].second)) : p0};
302
303 const std::vector<std::pair<std::int32_t, std::int32_t>> points{geometrize::bresenham(p0.first, p0.second, p1.first, p1.second)};
304 for(const auto& point : points) {
305 if(duplicates.insert(point).second) {
306 lines.push_back(geometrize::Scanline(point.second, point.first, point.first));
307 }
308 }
309 }
310
311 return geometrize::trimScanlines(lines, xMin, yMin, xMax, yMax);
312}
Here is the call graph for this function:

◆ rasterize() [5/10]

std::vector< geometrize::Scanline > geometrize::rasterize ( const geometrize::QuadraticBezier s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
315{
316 std::vector<geometrize::Scanline> scanlines;
317
318 std::vector<std::pair<std::int32_t, std::int32_t>> points;
319 const std::uint32_t pointCount{20};
320 for(std::uint32_t i = 0; i <= pointCount; i++) {
321 const float t{static_cast<float>(i) / static_cast<float>(pointCount)};
322 const float tp{1 - t};
323 const std::int32_t x{static_cast<std::int32_t>(tp * (tp * s.m_x1 + (t * s.m_cx)) + t * ((tp * s.m_cx) + (t * s.m_x2)))};
324 const std::int32_t y{static_cast<std::int32_t>(tp * (tp * s.m_y1 + (t * s.m_cy)) + t * ((tp * s.m_cy) + (t * s.m_y2)))};
325 points.push_back(std::make_pair(x, y));
326 }
327
328 // Prevent scanline overlap, it messes up the energy functions that rely on the scanlines not intersecting themselves
329 std::set<std::pair<std::int32_t, std::int32_t>> duplicates;
330
331 for(std::uint32_t i = 0; i < points.size() - 1; i++) {
332 const std::pair<std::int32_t, std::int32_t> p0{points[i]};
333 const std::pair<std::int32_t, std::int32_t> p1{points[i + 1]};
334
335 const std::vector<std::pair<std::int32_t, std::int32_t>> points{geometrize::bresenham(static_cast<std::int32_t>(p0.first), static_cast<std::int32_t>(p0.second), static_cast<std::int32_t>(p1.first), static_cast<std::int32_t>(p1.second))};
336 for(const std::pair<std::int32_t, std::int32_t>& point : points) {
337 if(duplicates.insert(point).second) {
338 scanlines.push_back(geometrize::Scanline(point.second, point.first, point.first));
339 }
340 }
341 }
342
343 return geometrize::trimScanlines(scanlines, xMin, yMin, xMax, yMax);
344}
Here is the call graph for this function:

◆ rasterize() [6/10]

std::vector< geometrize::Scanline > geometrize::rasterize ( const geometrize::Rectangle s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
347{
348 const std::int32_t x1{static_cast<std::int32_t>((std::fmin)(s.m_x1, s.m_x2))};
349 const std::int32_t x2{static_cast<std::int32_t>((std::fmax)(s.m_x1, s.m_x2))};
350 const std::int32_t y1{static_cast<std::int32_t>((std::fmin)(s.m_y1, s.m_y2))};
351 const std::int32_t y2{static_cast<std::int32_t>((std::fmax)(s.m_y1, s.m_y2))};
352
353 std::vector<geometrize::Scanline> lines;
354 for(std::int32_t y = y1; y <= y2; y++) {
355 lines.push_back(geometrize::Scanline(y, x1, x2));
356 }
357 return geometrize::trimScanlines(lines, xMin, yMin, xMax, yMax);
358}
Here is the call graph for this function:

◆ rasterize() [7/10]

std::vector< geometrize::Scanline > geometrize::rasterize ( const geometrize::RotatedEllipse s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
361{
362 const std::uint32_t pointCount{20};
363 std::vector<std::pair<float, float>> points = getPointsOnRotatedEllipse(s, pointCount);
364
365 std::vector<geometrize::Scanline> scanlines{geometrize::scanlinesForPolygon(points)};
366 return geometrize::trimScanlines(scanlines, xMin, yMin, xMax, yMax);
367}
std::vector< std::pair< float, float > > getPointsOnRotatedEllipse(const geometrize::RotatedEllipse &e, const std::size_t numPoints)
getPointsOnRotatedEllipse Calculates and returns a number of points on the given rotated ellipse.
Definition: rasterizer.cpp:57
std::vector< geometrize::Scanline > scanlinesForPolygon(const std::vector< std::pair< float, float > > &points)
scanlinesForPolygon Gets the scanlines for a series of points that make up an arbitrary polygon.
Definition: rasterizer.cpp:166
Here is the call graph for this function:

◆ rasterize() [8/10]

std::vector< geometrize::Scanline > geometrize::rasterize ( const geometrize::RotatedRectangle s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
370{
371 std::vector<geometrize::Scanline> scanlines{geometrize::scanlinesForPolygon(getCornerPoints(s))};
372 return geometrize::trimScanlines(scanlines, xMin, yMin, xMax, yMax);
373}
std::vector< std::pair< float, float > > getCornerPoints(const geometrize::RotatedRectangle &r)
getCornerPoints Gets the corner points of the given rotated rectangle.
Definition: rasterizer.cpp:30
Here is the call graph for this function:

◆ rasterize() [9/10]

std::vector< geometrize::Scanline > geometrize::rasterize ( const geometrize::Shape s,
std::int32_t  xMin,
std::int32_t  yMin,
std::int32_t  xMax,
std::int32_t  yMax 
)
195{
196 switch(s.getType()) {
198 return rasterize(static_cast<const geometrize::Rectangle&>(s), xMin, yMin, xMax, yMax);
200 return rasterize(static_cast<const geometrize::RotatedRectangle&>(s), xMin, yMin, xMax, yMax);
202 return rasterize(static_cast<const geometrize::Triangle&>(s), xMin, yMin, xMax, yMax);
204 return rasterize(static_cast<const geometrize::Ellipse&>(s), xMin, yMin, xMax, yMax);
206 return rasterize(static_cast<const geometrize::RotatedEllipse&>(s), xMin, yMin, xMax, yMax);
208 return rasterize(static_cast<const geometrize::Circle&>(s), xMin, yMin, xMax, yMax);
210 return rasterize(static_cast<const geometrize::Line&>(s), xMin, yMin, xMax, yMax);
212 return rasterize(static_cast<const geometrize::QuadraticBezier&>(s), xMin, yMin, xMax, yMax);
214 return rasterize(static_cast<const geometrize::Polyline&>(s), xMin, yMin, xMax, yMax);
215 default:
216 assert(0 && "Bad shape type");
217 return std::vector<geometrize::Scanline>{};
218 }
219}
std::vector< geometrize::Scanline > rasterize(const geometrize::Triangle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
Definition: rasterizer.cpp:375
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rasterize() [10/10]

std::vector< geometrize::Scanline > geometrize::rasterize ( const geometrize::Triangle s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
376{
377 std::vector<geometrize::Scanline> scanlines = geometrize::scanlinesForPolygon({
378 {static_cast<std::int32_t>(s.m_x1), static_cast<std::int32_t>(s.m_y1)},
379 {static_cast<std::int32_t>(s.m_x2), static_cast<std::int32_t>(s.m_y2)},
380 {static_cast<std::int32_t>(s.m_x3), static_cast<std::int32_t>(s.m_y3)}});
381
382 return geometrize::trimScanlines(scanlines, xMin, yMin, xMax, yMax);
383}
Here is the call graph for this function:

◆ rotate() [1/5]

void geometrize::rotate ( geometrize::Line s,
const float  angle 
)
638{
639 const float xMid = (s.m_x1 + s.m_x2) / 2;
640 const float yMid = (s.m_y1 + s.m_y2) / 2;
641
642 translate(s, -xMid, -yMid);
643
644 const float x1 = s.m_x1;
645 const float x2 = s.m_x2;
646 const float y1 = s.m_y1;
647 const float y2 = s.m_y2;
648 const float cosAngle = std::cos(angle);
649 const float sinAngle = std::sin(angle);
650
651 s.m_x1 = x1 * cosAngle - y1 * sinAngle;
652 s.m_y1 = x1 * sinAngle + y1 * cosAngle;
653 s.m_x2 = x2 * cosAngle - y2 * sinAngle;
654 s.m_y2 = x2 * sinAngle + y2 * cosAngle;
655
656 translate(s, xMid, yMid);
657}
void translate(geometrize::Triangle &s, const float x, const float y)
Definition: shapemutator.cpp:480
Here is the call graph for this function:

◆ rotate() [2/5]

void geometrize::rotate ( geometrize::RotatedEllipse s,
const float  angle 
)
660{
661 s.m_angle = wrapMinMax(s.m_angle + angle, 0, 360);
662}

◆ rotate() [3/5]

void geometrize::rotate ( geometrize::RotatedRectangle s,
const float  angle 
)
665{
666 s.m_angle = wrapMinMax(s.m_angle + angle, 0, 360);
667}

◆ rotate() [4/5]

void geometrize::rotate ( geometrize::Shape s,
const float  angle 
)
618{
619 switch(s.getType()) {
621 rotate(static_cast<geometrize::RotatedRectangle&>(s), angle);
622 break;
624 rotate(static_cast<geometrize::Triangle&>(s), angle);
625 break;
627 rotate(static_cast<geometrize::RotatedEllipse&>(s), angle);
628 break;
630 rotate(static_cast<geometrize::Line&>(s), angle);
631 break;
632 default:
633 break;
634 }
635}
void rotate(geometrize::Triangle &s, const float angle)
Definition: shapemutator.cpp:669
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rotate() [5/5]

void geometrize::rotate ( geometrize::Triangle s,
const float  angle 
)
670{
671 const float xMid = (s.m_x1 + s.m_x2 + s.m_x3) / 3;
672 const float yMid = (s.m_y1 + s.m_y2 + s.m_y3) / 3;
673
674 translate(s, -xMid, -yMid);
675
676 const float x1 = s.m_x1;
677 const float x2 = s.m_x2;
678 const float x3 = s.m_x3;
679 const float y1 = s.m_y1;
680 const float y2 = s.m_y2;
681 const float y3 = s.m_y3;
682 const float cosAngle = std::cos(angle);
683 const float sinAngle = std::sin(angle);
684
685 s.m_x1 = x1 * cosAngle - y1 * sinAngle;
686 s.m_y1 = x1 * sinAngle + y1 * cosAngle;
687 s.m_x2 = x2 * cosAngle - y2 * sinAngle;
688 s.m_y2 = x2 * sinAngle + y2 * cosAngle;
689 s.m_x3 = x3 * cosAngle - y3 * sinAngle;
690 s.m_y3 = x3 * sinAngle + y3 * cosAngle;
691
692 translate(s, xMid, yMid);
693}
Here is the call graph for this function:

◆ scale() [1/10]

void geometrize::scale ( geometrize::Circle s,
const float  scaleFactor 
)
526{
527 s.m_r *= scaleFactor;
528}

◆ scale() [2/10]

void geometrize::scale ( geometrize::Ellipse s,
const float  scaleFactor 
)
531{
532 s.m_rx *= scaleFactor;
533 s.m_ry *= scaleFactor;
534}

◆ scale() [3/10]

void geometrize::scale ( geometrize::Line s,
const float  scaleFactor 
)
537{
538 const float xMid = (s.m_x1 + s.m_x2) / 2;
539 const float yMid = (s.m_y1 + s.m_y2) / 2;
540
541 s.m_x1 = (s.m_x1 - xMid) * scaleFactor + xMid;
542 s.m_x2 = (s.m_x2 - xMid) * scaleFactor + xMid;
543
544 s.m_y1 = (s.m_y1 - yMid) * scaleFactor + yMid;
545 s.m_y2 = (s.m_y2 - yMid) * scaleFactor + yMid;
546}

◆ scale() [4/10]

void geometrize::scale ( geometrize::Polyline s,
const float  scaleFactor 
)
549{
550 std::vector<std::pair<float, float>> points;
551
552 for(std::size_t i = 0; i < s.m_points.size(); i+=2) {
553 if(i == s.m_points.size() - 1 || i == s.m_points.size()) {
554 continue;
555 }
556 const float x1 = s.m_points[i].first;
557 const float x2 = s.m_points[i + 1].first;
558 const float y1 = s.m_points[i].second;
559 const float y2 = s.m_points[i + 1].second;
560
561 const float xLen = (x1 + x2) / 2;
562 const float yLen = (y1 + y2) / 2;
563
564 points.push_back({(x1 - xLen) * scaleFactor + xLen, (y1 - yLen) * scaleFactor + yLen});
565 points.push_back({(x1 - xLen) * scaleFactor + xLen, (y2 - yLen) * scaleFactor + yLen});
566 }
567
568 s.m_points = points;
569}

◆ scale() [5/10]

void geometrize::scale ( geometrize::QuadraticBezier s,
const float  scaleFactor 
)
572{
573 assert(0 && "TODO");
574}

◆ scale() [6/10]

void geometrize::scale ( geometrize::Rectangle s,
const float  scaleFactor 
)
577{
578 const float xMid = (s.m_x1 + s.m_x2) / 2;
579 const float yMid = (s.m_y1 + s.m_y2) / 2;
580
581 s.m_x1 = (s.m_x1 - xMid) * scaleFactor + xMid;
582 s.m_y1 = (s.m_y1 - yMid) * scaleFactor + yMid;
583 s.m_x2 = (s.m_x2 - xMid) * scaleFactor + xMid;
584 s.m_y2 = (s.m_y2 - yMid) * scaleFactor + yMid;
585}

◆ scale() [7/10]

void geometrize::scale ( geometrize::RotatedEllipse s,
const float  scaleFactor 
)
588{
589 s.m_rx *= scaleFactor;
590 s.m_ry *= scaleFactor;
591}

◆ scale() [8/10]

void geometrize::scale ( geometrize::RotatedRectangle s,
const float  scaleFactor 
)
594{
595 const float xMid = (s.m_x1 + s.m_x2) / 2;
596 const float yMid = (s.m_y1 + s.m_y2) / 2;
597
598 s.m_x1 = (s.m_x1 - xMid) * scaleFactor + xMid;
599 s.m_y1 = (s.m_y1 - yMid) * scaleFactor + yMid;
600 s.m_x2 = (s.m_x2 - xMid) * scaleFactor + xMid;
601 s.m_y2 = (s.m_y2 - yMid) * scaleFactor + yMid;
602}

◆ scale() [9/10]

void geometrize::scale ( geometrize::Shape s,
const float  scaleFactor 
)
491{
492 switch(s.getType()) {
494 scale(static_cast<geometrize::Rectangle&>(s), scaleFactor);
495 break;
497 scale(static_cast<geometrize::RotatedRectangle&>(s), scaleFactor);
498 break;
500 scale(static_cast<geometrize::Triangle&>(s), scaleFactor);
501 break;
503 scale(static_cast<geometrize::Ellipse&>(s), scaleFactor);
504 break;
506 scale(static_cast<geometrize::RotatedEllipse&>(s), scaleFactor);
507 break;
509 scale(static_cast<geometrize::Circle&>(s), scaleFactor);
510 break;
512 scale(static_cast<geometrize::Line&>(s), scaleFactor);
513 break;
515 scale(static_cast<geometrize::QuadraticBezier&>(s), scaleFactor);
516 break;
518 scale(static_cast<geometrize::Polyline&>(s), scaleFactor);
519 break;
520 default:
521 assert(0 && "Bad shape type");
522 }
523}
void scale(geometrize::Triangle &s, const float scaleFactor)
Definition: shapemutator.cpp:604
Here is the call graph for this function:
Here is the caller graph for this function:

◆ scale() [10/10]

void geometrize::scale ( geometrize::Triangle s,
const float  scaleFactor 
)
605{
606 const float xMid = (s.m_x1 + s.m_x2 + s.m_x3) / 3;
607 const float yMid = (s.m_y1 + s.m_y2 + s.m_y3) / 3;
608
609 s.m_x1 = (s.m_x1 - xMid) * scaleFactor + xMid;
610 s.m_y1 = (s.m_y1 - yMid) * scaleFactor + yMid;
611 s.m_x2 = (s.m_x2 - xMid) * scaleFactor + xMid;
612 s.m_y2 = (s.m_y2 - yMid) * scaleFactor + yMid;
613 s.m_x3 = (s.m_x3 - xMid) * scaleFactor + xMid;
614 s.m_y3 = (s.m_y3 - yMid) * scaleFactor + yMid;
615}

◆ scanlinesContain()

bool geometrize::scanlinesContain ( const std::vector< geometrize::Scanline > &  first,
const std::vector< geometrize::Scanline > &  second 
)

scanlinesContain Returns true if the first vector of scanlines wholly contain the second vector of scanlines.

Parameters
firstFirst collection of scanlines.
secondSecond collection of scanlines.
Returns
True if the first set of scanlines wholly contains the second set, else false.
400{
401 for(const auto& s : second) {
402 bool contained = false;
403 for(const auto& f : first) {
404 if(f.y == s.y) {
405 if(f.x1 <= s.x1 && f.x2 >= s.x2) {
406 contained = true;
407 break;
408 }
409 }
410 }
411
412 if(!contained) {
413 return false;
414 }
415 }
416
417 return true;
418}
Here is the caller graph for this function:

◆ scanlinesForPolygon()

std::vector< geometrize::Scanline > geometrize::scanlinesForPolygon ( const std::vector< std::pair< float, float > > &  points)

scanlinesForPolygon Gets the scanlines for a series of points that make up an arbitrary polygon.

Parameters
pointsThe vertices of the polygon.
Returns
Scanlines for the polygon.
167{
168 std::vector<geometrize::Scanline> lines;
169
170 // Get the pixel outline of the polygon
171 std::vector<std::pair<std::int32_t, std::int32_t>> edges;
172 for(std::size_t i = 0; i < points.size(); i++) {
173 const std::pair<std::int32_t, std::int32_t> p1{static_cast<std::int32_t>(points[i].first), static_cast<std::int32_t>(points[i].second)};
174 const std::pair<std::int32_t, std::int32_t> p2{(i == (points.size() - 1)) ? std::make_pair(static_cast<std::int32_t>(points[0U].first), static_cast<std::int32_t>(points[0U].second)) : std::make_pair(static_cast<std::int32_t>(points[i + 1U].first), static_cast<std::int32_t>(points[i + 1U].second))};
175 const std::vector<std::pair<std::int32_t, std::int32_t>> p1p2{geometrize::bresenham(p1.first, p1.second, p2.first, p2.second)};
176 edges.insert(edges.end(), p1p2.begin(), p1p2.end());
177 }
178
179 // Convert outline to scanlines
180 std::map<std::int32_t, std::set<std::int32_t>> yToXs;
181 for(std::pair<std::int32_t, std::int32_t> point : edges) {
182 yToXs[point.second].insert(point.first);
183 }
184 for(const auto& it : yToXs) {
185 const geometrize::Scanline scanline(it.first,
186 *(std::min_element(it.second.begin(), it.second.end())),
187 *(std::max_element(it.second.begin(), it.second.end())));
188 lines.push_back(scanline);
189 }
190
191 return lines;
192}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ scanlinesOverlap()

bool geometrize::scanlinesOverlap ( const std::vector< geometrize::Scanline > &  first,
const std::vector< geometrize::Scanline > &  second 
)

scanlinesOverlap Returns true if any of the scanlines from the first vector overlap the second

Parameters
firstFirst collection of scanlines.
secondSecond collection of scanlines.
Returns
True if there are any overlaps, else false.
386{
387 for(const auto& f : first) {
388 for(const auto& s : second) {
389 if(f.y == s.y) {
390 if(f.x1 <= s.x2 && f.x2 >= s.x1) {
391 return true;
392 }
393 }
394 }
395 }
396 return false;
397}
Here is the caller graph for this function:

◆ setup() [1/10]

void geometrize::setup ( geometrize::Circle s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
73{
74 s.m_x = geometrize::commonutil::randomRange(xMin, xMax - 1);
75 s.m_y = geometrize::commonutil::randomRange(yMin, yMax - 1);
77}
Here is the call graph for this function:

◆ setup() [2/10]

void geometrize::setup ( geometrize::Ellipse s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
Here is the call graph for this function:

◆ setup() [3/10]

void geometrize::setup ( geometrize::Line s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
88{
89 const std::pair<std::int32_t, std::int32_t> startingPoint{std::make_pair(geometrize::commonutil::randomRange(xMin, xMax), geometrize::commonutil::randomRange(yMin, yMax - 1))};
90
91 s.m_x1 = geometrize::commonutil::clamp(startingPoint.first + geometrize::commonutil::randomRange(-32, 32), xMin, xMax - 1);
92 s.m_y1 = geometrize::commonutil::clamp(startingPoint.second + geometrize::commonutil::randomRange(-32, 32), yMin, yMax - 1);
93 s.m_x2 = geometrize::commonutil::clamp(startingPoint.first + geometrize::commonutil::randomRange(-32, 32), xMin, xMax - 1);
94 s.m_y2 = geometrize::commonutil::clamp(startingPoint.second + geometrize::commonutil::randomRange(-32, 32), yMin, yMax - 1);
95}
Here is the call graph for this function:

◆ setup() [4/10]

void geometrize::setup ( geometrize::Polyline s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
98{
99 const std::pair<std::int32_t, std::int32_t> startingPoint{std::make_pair(geometrize::commonutil::randomRange(xMin, xMax), geometrize::commonutil::randomRange(yMin, yMax - 1))};
100 for(std::int32_t i = 0; i < 4; i++) {
101 const std::pair<std::int32_t, std::int32_t> point{
102 geometrize::commonutil::clamp(startingPoint.first + geometrize::commonutil::randomRange(-32, 32), xMin, xMax - 1),
103 geometrize::commonutil::clamp(startingPoint.second + geometrize::commonutil::randomRange(-32, 32), yMin, yMax - 1)
104 };
105 s.m_points.push_back(point);
106 }
107}
Here is the call graph for this function:

◆ setup() [5/10]

void geometrize::setup ( geometrize::QuadraticBezier s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
110{
111 s.m_x1 = geometrize::commonutil::randomRange(xMin, xMax - 1);
112 s.m_y1 = geometrize::commonutil::randomRange(yMin, yMax - 1);
113 s.m_cx = geometrize::commonutil::randomRange(xMin, xMax - 1);
114 s.m_cy = geometrize::commonutil::randomRange(yMin, yMax - 1);
115 s.m_x2 = geometrize::commonutil::randomRange(xMin, xMax - 1);
116 s.m_y2 = geometrize::commonutil::randomRange(yMin, yMax - 1);
117}
Here is the call graph for this function:

◆ setup() [6/10]

void geometrize::setup ( geometrize::Rectangle s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
120{
121 s.m_x1 = geometrize::commonutil::randomRange(xMin, xMax - 1);
122 s.m_y1 = geometrize::commonutil::randomRange(yMin, yMax - 1);
123 s.m_x2 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x1) + geometrize::commonutil::randomRange(1, 32), xMin, xMax - 1);
124 s.m_y2 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y1) + geometrize::commonutil::randomRange(1, 32), yMin, yMax - 1);
125}
Here is the call graph for this function:

◆ setup() [7/10]

void geometrize::setup ( geometrize::RotatedEllipse s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
Here is the call graph for this function:

◆ setup() [8/10]

void geometrize::setup ( geometrize::RotatedRectangle s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
137{
138 s.m_x1 = geometrize::commonutil::randomRange(xMin, xMax - 1);
139 s.m_y1 = geometrize::commonutil::randomRange(yMin, yMax - 1);
140 s.m_x2 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_x1) + geometrize::commonutil::randomRange(1, 32), xMin, xMax);
141 s.m_y2 = geometrize::commonutil::clamp(static_cast<std::int32_t>(s.m_y1) + geometrize::commonutil::randomRange(1, 32), yMin, yMax);
143}
Here is the call graph for this function:

◆ setup() [9/10]

void geometrize::setup ( geometrize::Shape s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
38{
39 switch(s.getType()) {
41 setup(static_cast<geometrize::Rectangle&>(s), xMin, yMin, xMax, yMax);
42 break;
44 setup(static_cast<geometrize::RotatedRectangle&>(s), xMin, yMin, xMax, yMax);
45 break;
47 setup(static_cast<geometrize::Triangle&>(s), xMin, yMin, xMax, yMax);
48 break;
50 setup(static_cast<geometrize::Ellipse&>(s), xMin, yMin, xMax, yMax);
51 break;
53 setup(static_cast<geometrize::RotatedEllipse&>(s), xMin, yMin, xMax, yMax);
54 break;
56 setup(static_cast<geometrize::Circle&>(s), xMin, yMin, xMax, yMax);
57 break;
59 setup(static_cast<geometrize::Line&>(s), xMin, yMin, xMax, yMax);
60 break;
62 setup(static_cast<geometrize::QuadraticBezier&>(s), xMin, yMin, xMax, yMax);
63 break;
65 setup(static_cast<geometrize::Polyline&>(s), xMin, yMin, xMax, yMax);
66 break;
67 default:
68 assert(0 && "Bad shape type");
69 }
70}
void setup(geometrize::Triangle &s, const std::int32_t xMin, const std::int32_t yMin, const std::int32_t xMax, const std::int32_t yMax)
Definition: shapemutator.cpp:145
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setup() [10/10]

void geometrize::setup ( geometrize::Triangle s,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
Here is the call graph for this function:

◆ shapeContains()

bool geometrize::shapeContains ( const geometrize::Shape container,
const geometrize::Shape containee,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
426{
427 return geometrize::scanlinesContain(rasterize(container, xMin, yMin, xMax, yMax), rasterize(containee, xMin, yMin, xMax, yMax));
428}
bool scanlinesContain(const std::vector< geometrize::Scanline > &first, const std::vector< geometrize::Scanline > &second)
scanlinesContain Returns true if the first vector of scanlines wholly contain the second vector of sc...
Definition: rasterizer.cpp:399
Here is the call graph for this function:

◆ shapesOverlap()

bool geometrize::shapesOverlap ( const geometrize::Shape a,
const geometrize::Shape b,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
421{
422 return geometrize::scanlinesOverlap(geometrize::rasterize(a, xMin, yMin, xMax, yMax), geometrize::rasterize(b, xMin, yMin, xMax, yMax));
423}
bool scanlinesOverlap(const std::vector< geometrize::Scanline > &first, const std::vector< geometrize::Scanline > &second)
scanlinesOverlap Returns true if any of the scanlines from the first vector overlap the second
Definition: rasterizer.cpp:385
Here is the call graph for this function:

◆ shapeToPixels()

std::vector< std::pair< std::int32_t, std::int32_t > > geometrize::shapeToPixels ( const geometrize::Shape shape,
const std::int32_t  xMin,
const std::int32_t  yMin,
const std::int32_t  xMax,
const std::int32_t  yMax 
)
431{
432 const auto scanlines = geometrize::rasterize(shape, xMin, yMin, xMax, yMax);
433 std::vector<std::pair<std::int32_t, std::int32_t>> points = {};
434 for(const auto& scanline : scanlines) {
435 for(std::int32_t x = scanline.x1; x <= scanline.x2; x++) {
436 points.push_back({x, scanline.y});
437 }
438 }
439 return points;
440}
Here is the call graph for this function:

◆ translate() [1/10]

void geometrize::translate ( geometrize::Circle s,
const float  x,
const float  y 
)
421{
422 s.m_x += x;
423 s.m_y += y;
424}

◆ translate() [2/10]

void geometrize::translate ( geometrize::Ellipse s,
const float  x,
const float  y 
)
427{
428 s.m_x += x;
429 s.m_y += y;
430}

◆ translate() [3/10]

void geometrize::translate ( geometrize::Line s,
const float  x,
const float  y 
)
433{
434 s.m_x1 += x;
435 s.m_y1 += y;
436 s.m_x2 += x;
437 s.m_y2 += y;
438}

◆ translate() [4/10]

void geometrize::translate ( geometrize::Polyline s,
const float  x,
const float  y 
)
441{
442 for(auto& point : s.m_points) {
443 point.first += x;
444 point.second += y;
445 }
446}

◆ translate() [5/10]

void geometrize::translate ( geometrize::QuadraticBezier s,
const float  x,
const float  y 
)
449{
450 s.m_cx += x;
451 s.m_cy += y;
452 s.m_x1 += x;
453 s.m_y1 += y;
454 s.m_x2 += x;
455 s.m_y2 += y;
456}

◆ translate() [6/10]

void geometrize::translate ( geometrize::Rectangle s,
const float  x,
const float  y 
)
459{
460 s.m_x1 += x;
461 s.m_y1 += y;
462 s.m_x2 += x;
463 s.m_y2 += y;
464}

◆ translate() [7/10]

void geometrize::translate ( geometrize::RotatedEllipse s,
const float  x,
const float  y 
)
467{
468 s.m_x += x;
469 s.m_y += y;
470}

◆ translate() [8/10]

void geometrize::translate ( geometrize::RotatedRectangle s,
const float  x,
const float  y 
)
473{
474 s.m_x1 += x;
475 s.m_y1 += y;
476 s.m_x2 += x;
477 s.m_y2 += y;
478}

◆ translate() [9/10]

void geometrize::translate ( geometrize::Shape s,
const float  x,
const float  y 
)
386{
387 switch(s.getType()) {
389 translate(static_cast<geometrize::Rectangle&>(s), x, y);
390 break;
392 translate(static_cast<geometrize::RotatedRectangle&>(s), x, y);
393 break;
395 translate(static_cast<geometrize::Triangle&>(s), x, y);
396 break;
398 translate(static_cast<geometrize::Ellipse&>(s), x, y);
399 break;
401 translate(static_cast<geometrize::RotatedEllipse&>(s), x, y);
402 break;
404 translate(static_cast<geometrize::Circle&>(s), x, y);
405 break;
407 translate(static_cast<geometrize::Line&>(s), x, y);
408 break;
410 translate(static_cast<geometrize::QuadraticBezier&>(s), x, y);
411 break;
413 translate(static_cast<geometrize::Polyline&>(s), x, y);
414 break;
415 default:
416 assert(0 && "Bad shape type");
417 }
418}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ translate() [10/10]

void geometrize::translate ( geometrize::Triangle s,
const float  x,
const float  y 
)
481{
482 s.m_x1 += x;
483 s.m_y1 += y;
484 s.m_x2 += x;
485 s.m_y2 += y;
486 s.m_x3 += x;
487 s.m_y3 += y;
488}

◆ trimScanlines()

std::vector< geometrize::Scanline > geometrize::trimScanlines ( const std::vector< geometrize::Scanline > &  scanlines,
std::int32_t  minX,
std::int32_t  minY,
std::int32_t  maxX,
std::int32_t  maxY 
)

trimScanlines Crops the scanning width of an array of scanlines so they do not scan outside of the given area.

Parameters
scanlinesThe scanlines to crop.
minXThe minimum x value to crop to.
minYThe minimum y value to crop to.
maxXThe maximum x value to crop to.
maxYThe maximum y value to crop to.
Returns
A new vector of cropped scanlines.
24{
25 std::vector<geometrize::Scanline> trimmedScanlines;
26
27 for(const geometrize::Scanline& line : scanlines) {
28 if(line.y < minY || line.y >= maxY) {
29 continue;
30 }
31 if(line.x1 > line.x2) {
32 continue;
33 }
34 const float x1 = geometrize::commonutil::clamp(line.x1, minX, maxX - 1);
35 const float x2 = geometrize::commonutil::clamp(line.x2, minX, maxX - 1);
36 trimmedScanlines.emplace_back(Scanline(line.y, x1, x2));
37 }
38 return trimmedScanlines;
39}
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ allShapes

const std::array< ShapeTypes, static_cast< std::size_t >(ShapeTypes::SHAPE_COUNT)> geometrize::allShapes

◆ shapeTypeNames

const std::vector< std::pair< ShapeTypes, std::string > > geometrize::shapeTypeNames
Initial value:
=
{
{ ShapeTypes::RECTANGLE, "rectangle" },
{ ShapeTypes::ROTATED_RECTANGLE, "rotated_rectangle" },
{ ShapeTypes::TRIANGLE, "triangle" },
{ ShapeTypes::ELLIPSE, "ellipse" },
{ ShapeTypes::ROTATED_ELLIPSE, "rotated_ellipse" },
{ ShapeTypes::CIRCLE, "circle" },
{ ShapeTypes::LINE, "line" },
{ ShapeTypes::QUADRATIC_BEZIER, "quadratic_bezier" },
{ ShapeTypes::POLYLINE, "polyline" }
}

shapeTypeNames provides a convenient mapping to names of types of shape (all lower case, underscores instead of spaces e.g. rotated_ellipse).