diff --git a/src/Autoload/DrawingAlgos.gd b/src/Autoload/DrawingAlgos.gd index 69ffbe607..4dc1070e4 100644 --- a/src/Autoload/DrawingAlgos.gd +++ b/src/Autoload/DrawingAlgos.gd @@ -3,6 +3,73 @@ extends Node enum GradientDirection { TOP, BOTTOM, LEFT, RIGHT } +# Algorithm based on http://members.chello.at/easyfilter/bresenham.html +func get_ellipse_points(pos: Vector2, size: Vector2) -> Array: + var array := [] + var x0 := int(pos.x) + var x1 := pos.x + int(size.x - 1) + var y0 := int(pos.y) + var y1 := int(pos.y) + int(size.y - 1) + var a := int(abs(x1 - x0)) + var b := int(abs(y1 - x0)) + var b1 := b & 1 + var dx := 4 * (1 - a) * b * b + var dy := 4 * (b1 + 1) * a * a + var err := dx + dy + b1 * a * a + var e2 := 0 + + if x0 > x1: + x0 = x1 + x1 += a + + if y0 > y1: + y0 = y1 + +# warning-ignore:integer_division + y0 += (b + 1) / 2 + y1 = y0 - b1 + a *= 8 * a + b1 = 8 * b * b + + while x0 <= x1: + var v1 := Vector2(x1, y0) + var v2 := Vector2(x0, y0) + var v3 := Vector2(x0, y1) + var v4 := Vector2(x1, y1) + array.append(v1) + array.append(v2) + array.append(v3) + array.append(v4) + + e2 = 2 * err + + if e2 <= dy: + y0 += 1 + y1 -= 1 + dy += a + err += dy + + if e2 >= dx || 2 * err > dy: + x0 += 1 + x1 -= 1 + dx += b1 + err += dx + + while y0 - y1 < b: + var v1 := Vector2(x0 - 1, y0) + var v2 := Vector2(x1 + 1, y0) + var v3 := Vector2(x0 - 1, y1) + var v4 := Vector2(x1 + 1, y1) + array.append(v1) + array.append(v2) + array.append(v3) + array.append(v4) + y0 += 1 + y1 -= 1 + + return array + + func scale_3x(sprite: Image, tol: float = 50) -> Image: var scaled := Image.new() scaled.create(sprite.get_width() * 3, sprite.get_height() * 3, false, Image.FORMAT_RGBA8) diff --git a/src/Tools/EllipseTool.gd b/src/Tools/EllipseTool.gd index fe6de894f..c39dd151d 100644 --- a/src/Tools/EllipseTool.gd +++ b/src/Tools/EllipseTool.gd @@ -3,7 +3,7 @@ extends "res://src/Tools/ShapeDrawer.gd" func _get_shape_points_filled(size: Vector2) -> PoolVector2Array: var offsetted_size := size + Vector2.ONE * (_thickness - 1) - var border := _get_ellipse_points(Vector2.ZERO, offsetted_size) + var border := DrawingAlgos.get_ellipse_points(Vector2.ZERO, offsetted_size) var filling := [] var bitmap := _fill_bitmap_with_points(border, offsetted_size) @@ -36,7 +36,7 @@ func _get_shape_points_filled(size: Vector2) -> PoolVector2Array: func _get_shape_points(size: Vector2) -> PoolVector2Array: # Return ellipse with thickness 1 if _thickness == 1: - return PoolVector2Array(_get_ellipse_points(Vector2.ZERO, size)) + return PoolVector2Array(DrawingAlgos.get_ellipse_points(Vector2.ZERO, size)) var size_offset := Vector2.ONE * (_thickness - 1) var new_size := size + size_offset @@ -50,8 +50,8 @@ func _get_shape_points(size: Vector2) -> PoolVector2Array: # Adapted scanline algorithm to fill between 2 ellipses, to create a thicker ellipse var res_array := [] var border_ellipses := ( - _get_ellipse_points(Vector2.ZERO, new_size) - + _get_ellipse_points(size_offset, inner_ellipse_size) + DrawingAlgos.get_ellipse_points(Vector2.ZERO, new_size) + + DrawingAlgos.get_ellipse_points(size_offset, inner_ellipse_size) ) # Outer and inner ellipses var bitmap := _fill_bitmap_with_points(border_ellipses, new_size) var smallest_side := min(new_size.x, new_size.y) @@ -101,70 +101,3 @@ func _get_shape_points(size: Vector2) -> PoolVector2Array: res_array.append(pos + mirror_smallest_side + mirror_largest_side) return PoolVector2Array(res_array) - - -# Algorithm based on http://members.chello.at/easyfilter/bresenham.html -func _get_ellipse_points(pos: Vector2, size: Vector2) -> Array: - var array := [] - var x0 := int(pos.x) - var x1 := pos.x + int(size.x - 1) - var y0 := int(pos.y) - var y1 := int(pos.y) + int(size.y - 1) - var a := int(abs(x1 - x0)) - var b := int(abs(y1 - x0)) - var b1 := b & 1 - var dx := 4 * (1 - a) * b * b - var dy := 4 * (b1 + 1) * a * a - var err := dx + dy + b1 * a * a - var e2 := 0 - - if x0 > x1: - x0 = x1 - x1 += a - - if y0 > y1: - y0 = y1 - -# warning-ignore:integer_division - y0 += (b + 1) / 2 - y1 = y0 - b1 - a *= 8 * a - b1 = 8 * b * b - - while x0 <= x1: - var v1 := Vector2(x1, y0) - var v2 := Vector2(x0, y0) - var v3 := Vector2(x0, y1) - var v4 := Vector2(x1, y1) - array.append(v1) - array.append(v2) - array.append(v3) - array.append(v4) - - e2 = 2 * err - - if e2 <= dy: - y0 += 1 - y1 -= 1 - dy += a - err += dy - - if e2 >= dx || 2 * err > dy: - x0 += 1 - x1 -= 1 - dx += b1 - err += dx - - while y0 - y1 < b: - var v1 := Vector2(x0 - 1, y0) - var v2 := Vector2(x1 + 1, y0) - var v3 := Vector2(x0 - 1, y1) - var v4 := Vector2(x1 + 1, y1) - array.append(v1) - array.append(v2) - array.append(v3) - array.append(v4) - y0 += 1 - y1 -= 1 - - return array