diff --git a/Sources/geometrize-cli/main.swift b/Sources/geometrize-cli/main.swift index e4660dd..871370c 100644 --- a/Sources/geometrize-cli/main.swift +++ b/Sources/geometrize-cli/main.swift @@ -9,6 +9,7 @@ struct GeometrizeOptions: ParsableArguments { @Option(name: .shortAndLong, help: "Output file pathname.") var outputPath: String @Option(name: [.customShort("t"), .long], help: "White space separated list of shapes to use geometrizing image.") var shapeTypes: String = "rectangle" @Option(name: [.customShort("c"), .long], help: "The number of shapes to generate for the final output.") var shapeCount: UInt? + @Option(name: [.customShort("w"), .long], help: "Width of lines, polylines, bezier curves.") var lineWidth: UInt? @Flag(name: .shortAndLong, help: "Verbose output.") var verbose: Bool = false } @@ -90,8 +91,11 @@ print("Using shapes: \(shapeTypes.map { "\(type(of: $0))".dropLast(5) /* drop .T let shapeCount: Int = Int(options.shapeCount ?? 100) +let strokeWidth: Int = Int(options.lineWidth ?? 1) + let runnerOptions = ImageRunnerOptions( shapeTypes: shapeTypes, + strokeWidth: strokeWidth, alpha: 128, shapeCount: 100, maxShapeMutations: 100, @@ -108,7 +112,7 @@ var runner = ImageRunner(targetBitmap: targetBitmap) var shapeData: [ShapeResult] = [] // Hack to add a single background rectangle as the initial shape -let rect = Rectangle(x1: 0, y1: 0, x2: Double(targetBitmap.width), y2: Double(targetBitmap.height)) +let rect = Rectangle(strokeWidth: 1, x1: 0, y1: 0, x2: Double(targetBitmap.width), y2: Double(targetBitmap.height)) shapeData.append(ShapeResult(score: 0, color: targetBitmap.averageColor(), shape: rect)) var counter = 0 diff --git a/Sources/geometrize/ImageRunner.swift b/Sources/geometrize/ImageRunner.swift index 022a6ce..4488380 100644 --- a/Sources/geometrize/ImageRunner.swift +++ b/Sources/geometrize/ImageRunner.swift @@ -34,6 +34,9 @@ public struct ImageRunnerOptions { /// The shape types that the image runner shall use. var shapeTypes: [Shape.Type] + /// Width of Line, Polyline, QuadraticBezier + var strokeWidth: Int + /// The alpha/opacity of the shapes (0-255). var alpha: UInt8 @@ -53,8 +56,20 @@ public struct ImageRunnerOptions { /// If zero or do not form a rectangle, the entire target image is used i.e. (0, 0, imageWidth, imageHeight). var shapeBounds: ImageRunnerShapeBoundsOptions - public init(shapeTypes: [Shape.Type], alpha: UInt8, shapeCount: Int, maxShapeMutations: Int, seed: Int, maxThreads: Int, shapeBounds: ImageRunnerShapeBoundsOptions) { + public init( + shapeTypes: [Shape.Type], + strokeWidth: Int, + alpha: UInt8, + shapeCount: Int, + maxShapeMutations: Int, + seed: Int, + maxThreads: Int, + shapeBounds: ImageRunnerShapeBoundsOptions + ) { + precondition(strokeWidth > 0) + self.shapeTypes = shapeTypes + self.strokeWidth = strokeWidth self.alpha = alpha self.shapeCount = shapeCount self.maxShapeMutations = maxShapeMutations @@ -98,7 +113,7 @@ public struct ImageRunner { ) -> ShapeResult? { let types = options.shapeTypes - let shapeCreator: ShapeCreator = shapeCreator ?? makeDefaultShapeCreator(types: types) + let shapeCreator: ShapeCreator = shapeCreator ?? makeDefaultShapeCreator(types: types, strokeWidth: Double(options.strokeWidth)) model.setSeed(options.seed) diff --git a/Sources/geometrize/SVGExporter.swift b/Sources/geometrize/SVGExporter.swift index df3d3f8..98934d6 100644 --- a/Sources/geometrize/SVGExporter.swift +++ b/Sources/geometrize/SVGExporter.swift @@ -40,7 +40,7 @@ public struct SVGExporter { if shape.self is Line || shape.self is Polyline || shape.self is QuadraticBezier { styles += strokeAttrib(color: color) - styles += " stroke-width=\"1\" fill=\"none\" " + styles += " stroke-width=\"\(Int(shape.strokeWidth))\" fill=\"none\" " styles += strokeOpacityAttrib(color: color) } else { styles += fillAttrib(color: color) diff --git a/Sources/geometrize/ShapeCreator.swift b/Sources/geometrize/ShapeCreator.swift index cb355ef..08327c6 100644 --- a/Sources/geometrize/ShapeCreator.swift +++ b/Sources/geometrize/ShapeCreator.swift @@ -6,13 +6,13 @@ public typealias ShapeCreator = (inout SplitMix64) -> any Shape /// - Parameters: /// - types: The types of shapes to create. /// - Returns: The default shape creator. -public func makeDefaultShapeCreator(types: [Shape.Type]) -> ShapeCreator { +public func makeDefaultShapeCreator(types: [Shape.Type], strokeWidth: Double) -> ShapeCreator { return { generator in let index = types.index( types.startIndex, offsetBy: Int._random(in: 0...types.count - 1, using: &generator) ) let shapeType = types[index] - return shapeType.init() + return shapeType.init(strokeWidth: strokeWidth) } } diff --git a/Sources/geometrize/Shapes/Circle.swift b/Sources/geometrize/Shapes/Circle.swift index 32b4650..2a31cc2 100644 --- a/Sources/geometrize/Shapes/Circle.swift +++ b/Sources/geometrize/Shapes/Circle.swift @@ -1,24 +1,27 @@ import Foundation public final class Circle: Shape { + public var strokeWidth: Double public var x: Double // x-coordinate. public var y: Double // y-coordinate. public var r: Double // Radius. - public init() { + public init(strokeWidth: Double) { + self.strokeWidth = strokeWidth x = 0.0 y = 0.0 r = 0.0 } - public init(x: Double, y: Double, r: Double) { + public init(strokeWidth: Double, x: Double, y: Double, r: Double) { + self.strokeWidth = strokeWidth self.x = x self.y = y self.r = r } public func copy() -> Circle { - Circle(x: x, y: y, r: r) + Circle(strokeWidth: strokeWidth, x: x, y: y, r: r) } public func setup(x xRange: ClosedRange, y yRange: ClosedRange, using generator: inout SplitMix64) { diff --git a/Sources/geometrize/Shapes/Ellipse.swift b/Sources/geometrize/Shapes/Ellipse.swift index 52e13c4..9ef498c 100644 --- a/Sources/geometrize/Shapes/Ellipse.swift +++ b/Sources/geometrize/Shapes/Ellipse.swift @@ -1,19 +1,22 @@ import Foundation public final class Ellipse: Shape { + public var strokeWidth: Double public var x: Double // x-coordinate. public var y: Double // y-coordinate. public var rx: Double // x-radius. public var ry: Double // y-radius. - public init() { + public init(strokeWidth: Double) { + self.strokeWidth = strokeWidth x = 0.0 y = 0.0 rx = 0.0 ry = 0.0 } - public init(x: Double, y: Double, rx: Double, ry: Double) { + public init(strokeWidth: Double, x: Double, y: Double, rx: Double, ry: Double) { + self.strokeWidth = strokeWidth self.x = x self.y = y self.rx = rx @@ -21,7 +24,7 @@ public final class Ellipse: Shape { } public func copy() -> Ellipse { - Ellipse(x: x, y: y, rx: rx, ry: ry) + Ellipse(strokeWidth: strokeWidth, x: x, y: y, rx: rx, ry: ry) } public func setup(x xRange: ClosedRange, y yRange: ClosedRange, using generator: inout SplitMix64) { diff --git a/Sources/geometrize/Shapes/Line.swift b/Sources/geometrize/Shapes/Line.swift index 1adc5e2..749ff64 100644 --- a/Sources/geometrize/Shapes/Line.swift +++ b/Sources/geometrize/Shapes/Line.swift @@ -1,16 +1,19 @@ import Foundation public final class Line: Shape { + public var strokeWidth: Double public var x1, y1, x2, y2: Double - public init() { + public init(strokeWidth: Double) { + self.strokeWidth = strokeWidth x1 = 0.0 y1 = 0.0 x2 = 0.0 y2 = 0.0 } - public init(x1: Double, y1: Double, x2: Double, y2: Double) { + public init(strokeWidth: Double, x1: Double, y1: Double, x2: Double, y2: Double) { + self.strokeWidth = strokeWidth self.x1 = x1 self.y1 = y1 self.x2 = x2 @@ -18,7 +21,7 @@ public final class Line: Shape { } public func copy() -> Line { - Line(x1: x1, y1: y1, x2: x2, y2: y2) + Line(strokeWidth: strokeWidth, x1: x1, y1: y1, x2: x2, y2: y2) } public func setup(x xRange: ClosedRange, y yRange: ClosedRange, using generator: inout SplitMix64) { @@ -49,7 +52,7 @@ public final class Line: Shape { public func rasterize(x xRange: ClosedRange, y yRange: ClosedRange) -> [Scanline] { let lines = - drawThickLine(from: Point(x: Int(x1), y: Int(y1)), to: Point(x: Int(x2), y: Int(y2))) + drawThickLine(from: Point(x: Int(x1), y: Int(y1)), to: Point(x: Int(x2), y: Int(y2)), thickness: Int(strokeWidth)) .compactMap { Scanline(y: $0.y, x1: $0.x, x2: $0.x).trimmed(x: xRange, y: yRange) } diff --git a/Sources/geometrize/Shapes/Polyline.swift b/Sources/geometrize/Shapes/Polyline.swift index 4965d47..8371820 100644 --- a/Sources/geometrize/Shapes/Polyline.swift +++ b/Sources/geometrize/Shapes/Polyline.swift @@ -1,18 +1,21 @@ import Foundation public final class Polyline: Shape { + public var strokeWidth: Double public var points: [Point] - public init() { + public init(strokeWidth: Double) { + self.strokeWidth = strokeWidth points = [] } - public init(points: [Point]) { + public init(strokeWidth: Double, points: [Point]) { + self.strokeWidth = strokeWidth self.points = points } public func copy() -> Polyline { - Polyline(points: points) + Polyline(strokeWidth: strokeWidth, points: points) } public func setup(x xRange: ClosedRange, y yRange: ClosedRange, using generator: inout SplitMix64) { @@ -49,7 +52,7 @@ public final class Polyline: Shape { for i in 0..(p0), to: Point(p1)) + let points = drawThickLine(from: Point(p0), to: Point(p1), thickness: Int(strokeWidth)) for point in points { if !duplicates.contains(point) { duplicates.insert(point) diff --git a/Sources/geometrize/Shapes/QuadraticBezier.swift b/Sources/geometrize/Shapes/QuadraticBezier.swift index 4449544..f489c66 100644 --- a/Sources/geometrize/Shapes/QuadraticBezier.swift +++ b/Sources/geometrize/Shapes/QuadraticBezier.swift @@ -2,6 +2,7 @@ import Foundation import Algorithms public final class QuadraticBezier: Shape { + public var strokeWidth: Double public var x1: Double // First x-coordinate. public var y1: Double // First y-coordinate. public var x2: Double // Second x-coordinate. @@ -9,7 +10,8 @@ public final class QuadraticBezier: Shape { public var cx: Double // Control point x-coordinate. public var cy: Double // Control point y-coordinate. - public init() { + public init(strokeWidth: Double) { + self.strokeWidth = strokeWidth cx = 0.0 cy = 0.0 x1 = 0.0 @@ -18,7 +20,8 @@ public final class QuadraticBezier: Shape { y2 = 0.0 } - public init(cx: Double, cy: Double, x1: Double, y1: Double, x2: Double, y2: Double) { + public init(strokeWidth: Double, cx: Double, cy: Double, x1: Double, y1: Double, x2: Double, y2: Double) { + self.strokeWidth = strokeWidth self.cx = cx self.cy = cy self.x1 = x1 @@ -28,7 +31,7 @@ public final class QuadraticBezier: Shape { } public func copy() -> QuadraticBezier { - QuadraticBezier(cx: cx, cy: cy, x1: x1, y1: y1, x2: x2, y2: y2) + QuadraticBezier(strokeWidth: strokeWidth, cx: cx, cy: cy, x1: x1, y1: y1, x2: x2, y2: y2) } public func setup(x xRange: ClosedRange, y yRange: ClosedRange, using generator: inout SplitMix64) { @@ -72,7 +75,7 @@ public final class QuadraticBezier: Shape { // Prevent scanline overlap, it messes up the energy functions that rely on the scanlines not intersecting themselves var duplicates: Set> = Set() for (from, to) in points.adjacentPairs() { - for point in drawThickLine(from: from, to: to) { + for point in drawThickLine(from: from, to: to, thickness: Int(strokeWidth)) { if !duplicates.contains(point) { duplicates.insert(point) if let trimmed = Scanline(y: point.y, x1: point.x, x2: point.x).trimmed(x: xRange, y: yRange) { diff --git a/Sources/geometrize/Shapes/Rectangle.swift b/Sources/geometrize/Shapes/Rectangle.swift index 1808bc8..7a43827 100644 --- a/Sources/geometrize/Shapes/Rectangle.swift +++ b/Sources/geometrize/Shapes/Rectangle.swift @@ -2,16 +2,19 @@ import Foundation // Represents a rectangle. public final class Rectangle: Shape { + public var strokeWidth: Double public var x1, y1, x2, y2: Double - required public init() { + required public init(strokeWidth: Double) { + self.strokeWidth = strokeWidth x1 = 0.0 y1 = 0.0 x2 = 0.0 y2 = 0.0 } - public init(x1: Double, y1: Double, x2: Double, y2: Double) { + public init(strokeWidth: Double, x1: Double, y1: Double, x2: Double, y2: Double) { + self.strokeWidth = strokeWidth self.x1 = x1 self.y1 = y1 self.x2 = x2 @@ -20,11 +23,11 @@ public final class Rectangle: Shape { // Rectangle taking whole size of canvas public convenience init(canvasWidth width: Int, height: Int) { - self.init(x1: 0.0, y1: 0.0, x2: Double(width), y2: Double(height)) + self.init(strokeWidth: 1, x1: 0.0, y1: 0.0, x2: Double(width), y2: Double(height)) } public func copy() -> Rectangle { - Rectangle(x1: x1, y1: y1, x2: x2, y2: y2) + Rectangle(strokeWidth: strokeWidth, x1: x1, y1: y1, x2: x2, y2: y2) } public func setup(x xRange: ClosedRange, y yRange: ClosedRange, using generator: inout SplitMix64) { diff --git a/Sources/geometrize/Shapes/RotatedEllipse.swift b/Sources/geometrize/Shapes/RotatedEllipse.swift index 48ae679..044b0c2 100644 --- a/Sources/geometrize/Shapes/RotatedEllipse.swift +++ b/Sources/geometrize/Shapes/RotatedEllipse.swift @@ -2,13 +2,15 @@ import Foundation // Represents a rotated ellipse. public final class RotatedEllipse: Shape { + public var strokeWidth: Double public var x: Double // x-coordinate. public var y: Double // y-coordinate. public var rx: Double // x-radius. public var ry: Double // y-radius. public var angleDegrees: Double // Rotation angle in degrees. - public required init() { + public required init(strokeWidth: Double) { + self.strokeWidth = strokeWidth x = 0.0 y = 0.0 rx = 0.0 @@ -16,7 +18,8 @@ public final class RotatedEllipse: Shape { angleDegrees = 0.0 } - public init(x: Double, y: Double, rx: Double, ry: Double, angleDegrees: Double) { + public init(strokeWidth: Double, x: Double, y: Double, rx: Double, ry: Double, angleDegrees: Double) { + self.strokeWidth = strokeWidth self.x = x self.y = y self.rx = rx @@ -25,7 +28,7 @@ public final class RotatedEllipse: Shape { } public func copy() -> RotatedEllipse { - RotatedEllipse(x: x, y: y, rx: rx, ry: ry, angleDegrees: angleDegrees) + RotatedEllipse(strokeWidth: strokeWidth, x: x, y: y, rx: rx, ry: ry, angleDegrees: angleDegrees) } public func setup(x xRange: ClosedRange, y yRange: ClosedRange, using generator: inout SplitMix64) { diff --git a/Sources/geometrize/Shapes/RotatedRectangle.swift b/Sources/geometrize/Shapes/RotatedRectangle.swift index fef2ec7..d4a4440 100644 --- a/Sources/geometrize/Shapes/RotatedRectangle.swift +++ b/Sources/geometrize/Shapes/RotatedRectangle.swift @@ -2,13 +2,15 @@ import Foundation /// Represents a rotated rectangle. public final class RotatedRectangle: Shape { + public var strokeWidth: Double public var x1: Double public var y1: Double public var x2: Double public var y2: Double public var angleDegrees: Double - public required init() { + public required init(strokeWidth: Double) { + self.strokeWidth = strokeWidth x1 = 0.0 y1 = 0.0 x2 = 0.0 @@ -16,7 +18,8 @@ public final class RotatedRectangle: Shape { angleDegrees = 0.0 } - public init(x1: Double, y1: Double, x2: Double, y2: Double, angleDegrees: Double) { + public init(strokeWidth: Double, x1: Double, y1: Double, x2: Double, y2: Double, angleDegrees: Double) { + self.strokeWidth = strokeWidth self.x1 = x1 self.y1 = y1 self.x2 = x2 @@ -25,7 +28,7 @@ public final class RotatedRectangle: Shape { } public func copy() -> RotatedRectangle { - RotatedRectangle(x1: x1, y1: y1, x2: x2, y2: y2, angleDegrees: angleDegrees) + RotatedRectangle(strokeWidth: strokeWidth, x1: x1, y1: y1, x2: x2, y2: y2, angleDegrees: angleDegrees) } public func setup(x xRange: ClosedRange, y yRange: ClosedRange, using generator: inout SplitMix64) { diff --git a/Sources/geometrize/Shapes/Shape.swift b/Sources/geometrize/Shapes/Shape.swift index d3d4f5f..9eecaf0 100644 --- a/Sources/geometrize/Shapes/Shape.swift +++ b/Sources/geometrize/Shapes/Shape.swift @@ -1,7 +1,9 @@ import Foundation public protocol Shape: AnyObject, CustomStringConvertible { - init() + var strokeWidth: Double { get } + + init(strokeWidth: Double) func copy() -> Self diff --git a/Sources/geometrize/Shapes/Triangle.swift b/Sources/geometrize/Shapes/Triangle.swift index eb2ecc3..39ba5d0 100644 --- a/Sources/geometrize/Shapes/Triangle.swift +++ b/Sources/geometrize/Shapes/Triangle.swift @@ -1,6 +1,7 @@ import Foundation public final class Triangle: Shape { + public var strokeWidth: Double public var x1: Double // First x-coordinate. public var y1: Double // First y-coordinate. public var x2: Double // Second x-coordinate. @@ -8,7 +9,8 @@ public final class Triangle: Shape { public var x3: Double // Third x-coordinate. public var y3: Double // Third y-coordinate. - public init() { + public init(strokeWidth: Double) { + self.strokeWidth = strokeWidth x1 = 0.0 y1 = 0.0 x2 = 0.0 @@ -17,7 +19,8 @@ public final class Triangle: Shape { y3 = 0.0 } - public init(x1: Double, y1: Double, x2: Double, y2: Double, x3: Double, y3: Double) { + public init(strokeWidth: Double, x1: Double, y1: Double, x2: Double, y2: Double, x3: Double, y3: Double) { + self.strokeWidth = strokeWidth self.x1 = x1 self.y1 = y1 self.x2 = x2 @@ -27,7 +30,7 @@ public final class Triangle: Shape { } public func copy() -> Triangle { - Triangle(x1: x1, y1: y1, x2: x2, y2: y2, x3: x3, y3: y3) + Triangle(strokeWidth: strokeWidth, x1: x1, y1: y1, x2: x2, y2: y2, x3: x3, y3: y3) } public func setup(x xRange: ClosedRange, y yRange: ClosedRange, using generator: inout SplitMix64) { diff --git a/Tests/geometrizeTests/BitmapDownsampleTests.swift b/Tests/geometrizeTests/BitmapDownsampleTests.swift index aa31a2e..4bdba26 100644 --- a/Tests/geometrizeTests/BitmapDownsampleTests.swift +++ b/Tests/geometrizeTests/BitmapDownsampleTests.swift @@ -10,14 +10,14 @@ final class BitmapDownsampleTests: XCTestCase { var bitmap = Bitmap(width: width, height: height, color: .white) bitmap.draw( lines: - Ellipse(x: 250.0, y: 250.0, rx: 245.0, ry: 100.0) + Ellipse(strokeWidth: 1, x: 250.0, y: 250.0, rx: 245.0, ry: 100.0) .rasterize(x: xRange, y: yRange), color: .red.withAlphaComponent(200) ) bitmap.draw( lines: - Ellipse(x: 250.0, y: 250.0, rx: 100.0, ry: 245.0) + Ellipse(strokeWidth: 1, x: 250.0, y: 250.0, rx: 100.0, ry: 245.0) .rasterize(x: xRange, y: yRange), color: .green.withAlphaComponent(200) diff --git a/Tests/geometrizeTests/CircleTest.swift b/Tests/geometrizeTests/CircleTest.swift index 2f98e9d..dca38a8 100644 --- a/Tests/geometrizeTests/CircleTest.swift +++ b/Tests/geometrizeTests/CircleTest.swift @@ -10,35 +10,35 @@ final class CircleTests: XCTestCase { var bitmap = Bitmap(width: width, height: height, color: .white) bitmap.draw( lines: - Circle(x: 250.0, y: 250.0, r: 275.0) + Circle(strokeWidth: 1, x: 250.0, y: 250.0, r: 275.0) .rasterize(x: xRange, y: yRange), color: .red ) bitmap.draw( lines: - Circle(x: 330.0, y: 330.0, r: 250) + Circle(strokeWidth: 1, x: 330.0, y: 330.0, r: 250) .rasterize(x: xRange, y: yRange), color: .green.withAlphaComponent(200) ) bitmap.draw( lines: - Circle(x: 0.0, y: 0.0, r: 133.5) + Circle(strokeWidth: 1, x: 0.0, y: 0.0, r: 133.5) .rasterize(x: xRange, y: yRange), color: .blue.withAlphaComponent(128) ) bitmap.draw( lines: - Circle(x: 499.0, y: 0.0, r: 77.0) + Circle(strokeWidth: 1, x: 499.0, y: 0.0, r: 77.0) .rasterize(x: xRange, y: yRange), color: .magenta ) bitmap.draw( lines: - Circle(x: 250.0, y: 250.0, r: 100.0) + Circle(strokeWidth: 1, x: 250.0, y: 250.0, r: 100.0) .rasterize(x: xRange, y: yRange), color: .cyan diff --git a/Tests/geometrizeTests/CoreTests.swift b/Tests/geometrizeTests/CoreTests.swift index 16fedf4..4a7c931 100644 --- a/Tests/geometrizeTests/CoreTests.swift +++ b/Tests/geometrizeTests/CoreTests.swift @@ -122,7 +122,7 @@ final class CoreTests: XCTestCase { var bitmapBuffer = Bitmap(stringLiteral: try String(contentsOf: Bundle.module.url(forResource: "hillClimb buffer bitmap", withExtension: "txt")!)) let bitmapBufferOnExit = Bitmap(stringLiteral: try String(contentsOf: Bundle.module.url(forResource: "hillClimb buffer bitmap on exit", withExtension: "txt")!)) - let rectangle = Rectangle(x1: 281, y1: 193, x2: 309, y2: 225) + let rectangle = Rectangle(strokeWidth: 1, x1: 281, y1: 193, x2: 309, y2: 225) // rectangle.setupImplementation = { r in // r.setup(xMin: 0, yMin: 0, xMax: bitmapTarget.width, yMax: bitmapTarget.height) // } @@ -136,7 +136,7 @@ final class CoreTests: XCTestCase { // hillClimb return state State(score: 0.162824, alpha: 128, shape: Rectangle(x1=272,y1=113,x2=355,y2=237)) - let rectangleOnExit = Rectangle(x1: 272, y1: 113, x2: 355, y2: 237) + let rectangleOnExit = Rectangle(strokeWidth: 1, x1: 272, y1: 113, x2: 355, y2: 237) // rectangleOnExit.setupImplementation = { r in // r.setup(xMin: 0, yMin: 0, xMax: bitmapTarget.width, yMax: bitmapTarget.height) // } diff --git a/Tests/geometrizeTests/EllipseTests.swift b/Tests/geometrizeTests/EllipseTests.swift index 1b6a354..f9bb0c1 100644 --- a/Tests/geometrizeTests/EllipseTests.swift +++ b/Tests/geometrizeTests/EllipseTests.swift @@ -10,14 +10,14 @@ final class EllipseTests: XCTestCase { var bitmap = Bitmap(width: width, height: height, color: .white) bitmap.draw( lines: - Ellipse(x: 250.0, y: 250.0, rx: 245.0, ry: 100.0) + Ellipse(strokeWidth: 1, x: 250.0, y: 250.0, rx: 245.0, ry: 100.0) .rasterize(x: xRange, y: yRange), color: .red.withAlphaComponent(200) ) bitmap.draw( lines: - Ellipse(x: 250.0, y: 250.0, rx: 100.0, ry: 245.0) + Ellipse(strokeWidth: 1, x: 250.0, y: 250.0, rx: 100.0, ry: 245.0) .rasterize(x: xRange, y: yRange), color: .green.withAlphaComponent(200) diff --git a/Tests/geometrizeTests/ImageRunnerTests.swift b/Tests/geometrizeTests/ImageRunnerTests.swift index a03cf13..b4620da 100644 --- a/Tests/geometrizeTests/ImageRunnerTests.swift +++ b/Tests/geometrizeTests/ImageRunnerTests.swift @@ -20,6 +20,7 @@ final class ImageRunnerTests: XCTestCase { let options = ImageRunnerOptions( shapeTypes: [RotatedEllipse.self], + strokeWidth: 1, alpha: 128, shapeCount: 500, maxShapeMutations: 100, @@ -36,7 +37,7 @@ final class ImageRunnerTests: XCTestCase { var shapeData: [ShapeResult] = [] // Hack to add a single background rectangle as the initial shape - let rect = Rectangle(x1: 0, y1: 0, x2: Double(targetBitmap.width), y2: Double(targetBitmap.height)) + let rect = Rectangle(strokeWidth: 1, x1: 0, y1: 0, x2: Double(targetBitmap.width), y2: Double(targetBitmap.height)) shapeData.append(ShapeResult(score: 0, color: targetBitmap.averageColor(), shape: rect)) var counter = 0 diff --git a/Tests/geometrizeTests/LineTests.swift b/Tests/geometrizeTests/LineTests.swift index 7c3a089..3c658f8 100644 --- a/Tests/geometrizeTests/LineTests.swift +++ b/Tests/geometrizeTests/LineTests.swift @@ -11,9 +11,9 @@ final class LineTests: XCTestCase { var lines: [Scanline] = [] let shift: Double = 10.0 for x in stride(from: shift, through: Double(width) - shift, by: shift) { - lines += Line(x1: x, y1: shift, x2: Double(width) - shift, y2: Double(width) - shift) + lines += Line(strokeWidth: 1, x1: x, y1: shift, x2: Double(width) - shift, y2: Double(width) - shift) .rasterize(x: xRange, y: yRange) - lines += Line(x1: x, y1: shift, x2: shift, y2: Double(height) - shift) + lines += Line(strokeWidth: 1, x1: x, y1: shift, x2: shift, y2: Double(height) - shift) .rasterize(x: xRange, y: yRange) } bitmap.draw(lines: lines, color: .blue) @@ -40,10 +40,10 @@ func scaleScanlinesTrimmed(width: Int, height: Int, step: Int, tickHeight: Int = lines += stride(from: 0, through: width, by: step) .map { i -> [Scanline] in let lines: [Scanline] = - Line(x1: Double(i - step / 5), y1: 0.0, x2: Double(i + step / 5), y2: 0.0) + Line(strokeWidth: 1, x1: Double(i - step / 5), y1: 0.0, x2: Double(i + step / 5), y2: 0.0) .rasterize(x: xRange, y: yRange) + - Line(x1: Double(i - step / 5), y1: yMaxDouble, x2: Double(i + step / 5), y2: yMaxDouble) + Line(strokeWidth: 1, x1: Double(i - step / 5), y1: yMaxDouble, x2: Double(i + step / 5), y2: yMaxDouble) .rasterize(x: xRange, y: yRange) return lines } @@ -51,10 +51,10 @@ func scaleScanlinesTrimmed(width: Int, height: Int, step: Int, tickHeight: Int = // Ticks on horizontal line lines += stride(from: step, to: width, by: step) .map { i -> [Scanline] in - Line(x1: Double(i), y1: 0.0, x2: Double(i), y2: tickHeightDouble) + Line(strokeWidth: 1, x1: Double(i), y1: 0.0, x2: Double(i), y2: tickHeightDouble) .rasterize(x: xRange, y: yRange) + - Line(x1: Double(i), y1: Double(height - tickHeight - 1), x2: Double(i), y2: yMaxDouble) + Line(strokeWidth: 1, x1: Double(i), y1: Double(height - tickHeight - 1), x2: Double(i), y2: yMaxDouble) .rasterize(x: xRange, y: yRange) } .flatMap { $0 } @@ -62,10 +62,10 @@ func scaleScanlinesTrimmed(width: Int, height: Int, step: Int, tickHeight: Int = lines += stride(from: 0, through: height, by: step) .map { i -> [Scanline] in let lines: [Scanline] = - Line(x1: 0.0, y1: Double(i - step / 5), x2: 0.0, y2: Double(i + step / 5)) + Line(strokeWidth: 1, x1: 0.0, y1: Double(i - step / 5), x2: 0.0, y2: Double(i + step / 5)) .rasterize(x: xRange, y: yRange) + - Line(x1: xMaxDouble, y1: Double(i - step / 5), x2: xMaxDouble, y2: Double(i + step / 5)) + Line(strokeWidth: 1, x1: xMaxDouble, y1: Double(i - step / 5), x2: xMaxDouble, y2: Double(i + step / 5)) .rasterize(x: xRange, y: yRange) return lines } @@ -73,10 +73,10 @@ func scaleScanlinesTrimmed(width: Int, height: Int, step: Int, tickHeight: Int = // Ticks on vertical line lines += stride(from: step, to: height, by: step) .map { i -> [Scanline] in - Line(x1: 0.0, y1: Double(i), x2: tickHeightDouble, y2: Double(i)) + Line(strokeWidth: 1, x1: 0.0, y1: Double(i), x2: tickHeightDouble, y2: Double(i)) .rasterize(x: xRange, y: yRange) + - Line(x1: Double(width - tickHeight - 1), y1: Double(i), x2: xMaxDouble, y2: Double(i)) + Line(strokeWidth: 1, x1: Double(width - tickHeight - 1), y1: Double(i), x2: xMaxDouble, y2: Double(i)) .rasterize(x: xRange, y: yRange) } .flatMap { $0 } diff --git a/Tests/geometrizeTests/QuadraticBezierTests.swift b/Tests/geometrizeTests/QuadraticBezierTests.swift index 2df39b2..47e7b73 100644 --- a/Tests/geometrizeTests/QuadraticBezierTests.swift +++ b/Tests/geometrizeTests/QuadraticBezierTests.swift @@ -10,7 +10,7 @@ final class QuadraticBezierTests: XCTestCase { var bitmap = Bitmap(width: width, height: height, color: .red) bitmap.draw( lines: - QuadraticBezier(cx: 327.0, cy: 295.0, x1: 57.0, y1: 542.0, x2: 190.0, y2: 216.0) + QuadraticBezier(strokeWidth: 1, cx: 327.0, cy: 295.0, x1: 57.0, y1: 542.0, x2: 190.0, y2: 216.0) .rasterize(x: xRange, y: yRange), color: .white diff --git a/Tests/geometrizeTests/TriangleTests.swift b/Tests/geometrizeTests/TriangleTests.swift index 7e0b4b7..f916ab6 100644 --- a/Tests/geometrizeTests/TriangleTests.swift +++ b/Tests/geometrizeTests/TriangleTests.swift @@ -10,14 +10,14 @@ final class TriangleTests: XCTestCase { var bitmap = Bitmap(width: width, height: height, color: .white) bitmap.draw( lines: - Triangle(x1: 20, y1: 20, x2: 480, y2: 300, x3: 100, y3: 480) + Triangle(strokeWidth: 1, x1: 20, y1: 20, x2: 480, y2: 300, x3: 100, y3: 480) .rasterize(x: xRange, y: yRange), color: .yellow ) bitmap.draw( lines: - Triangle(x1: 510, y1: -10, x2: 250, y2: 505, x3: -5, y3: 270) + Triangle(strokeWidth: 1, x1: 510, y1: -10, x2: 250, y2: 505, x3: -5, y3: 270) .rasterize(x: xRange, y: yRange), color: .red.withAlphaComponent(128)