1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-30 23:19:49 +00:00

Make circle brushes scale properly, with support for even-numebered diameters

Also reverts commit 488cf0cc93
This commit is contained in:
Emmanouil Papadeas 2022-09-09 00:10:34 +03:00
parent dee49b61bf
commit d34e69579f
3 changed files with 38 additions and 56 deletions

View file

@ -42,7 +42,6 @@ func get_ellipse_points(pos: Vector2, size: Vector2) -> Array:
array.append(v4)
e2 = 2 * err
if e2 <= dy:
y0 += 1
y1 -= 1
@ -70,6 +69,37 @@ func get_ellipse_points(pos: Vector2, size: Vector2) -> Array:
return array
func get_ellipse_points_filled(pos: Vector2, size: Vector2, thickness := 1) -> PoolVector2Array:
var offsetted_size := size + Vector2.ONE * (thickness - 1)
var border := get_ellipse_points(pos, offsetted_size)
var filling := []
for x in range(1, ceil(offsetted_size.x / 2)):
var fill := false
var prev_is_true := false
for y in range(0, ceil(offsetted_size.y / 2)):
var top_l_p := Vector2(x, y)
var bit := border.has(pos + top_l_p)
if bit and not fill:
prev_is_true = true
continue
if not bit and (fill or prev_is_true):
filling.append(pos + top_l_p)
filling.append(pos + Vector2(x, offsetted_size.y - y - 1))
filling.append(pos + Vector2(offsetted_size.x - x - 1, y))
filling.append(pos + Vector2(offsetted_size.x - x - 1, offsetted_size.y - y - 1))
if prev_is_true:
fill = true
prev_is_true = false
elif bit and fill:
break
return PoolVector2Array(border + filling)
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)

View file

@ -214,9 +214,7 @@ func _prepare_tool() -> void:
var strength := _strength
if Global.pressure_sensitivity_mode == Global.PressureSensitivity.ALPHA:
strength *= Tools.pen_pressure
_drawer.pixel_perfect = false
if _brush_size == 1 and _brush.type == Brushes.PIXEL:
_drawer.pixel_perfect = Tools.pixel_perfect
_drawer.pixel_perfect = Tools.pixel_perfect if _brush_size == 1 else false
_drawer.horizontal_mirror = Tools.horizontal_mirror
_drawer.vertical_mirror = Tools.vertical_mirror
_drawer.color_op.strength = strength
@ -300,36 +298,18 @@ func _compute_draw_tool_pixel(position: Vector2) -> PoolVector2Array:
return result
# Algorithm based on http://members.chello.at/easyfilter/bresenham.html
# Compute the array of coordinates that should be drawn
func _compute_draw_tool_circle(position: Vector2, fill := false) -> PoolVector2Array:
var size := Vector2(_brush_size, _brush_size)
var pos = position - (size / 2).floor()
if _circle_tool_shortcut:
return _draw_tool_circle_from_map(position)
var result := PoolVector2Array()
var r := _brush_size
var x := -r
var y := 0
var err := 2 - r * 2
var draw := true
if fill:
result.append(position)
while x < 0:
if draw:
for i in range(1 if fill else -x, -x + 1):
result.append(position + Vector2(-i, y))
result.append(position + Vector2(-y, -i))
result.append(position + Vector2(i, -y))
result.append(position + Vector2(y, i))
draw = not fill
r = err
if r <= y:
y += 1
err += y * 2 + 1
draw = true
if r > x || err > y:
x += 1
err += x * 2 + 1
result = DrawingAlgos.get_ellipse_points_filled(pos, size)
else:
result = DrawingAlgos.get_ellipse_points(pos, size)
return result

View file

@ -2,35 +2,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 := DrawingAlgos.get_ellipse_points(Vector2.ZERO, offsetted_size)
var filling := []
var bitmap := _fill_bitmap_with_points(border, offsetted_size)
for x in range(1, ceil(offsetted_size.x / 2)):
var fill := false
var prev_is_true := false
for y in range(0, ceil(offsetted_size.y / 2)):
var top_l_p := Vector2(x, y)
var bit := bitmap.get_bit(top_l_p)
if bit and not fill:
prev_is_true = true
continue
if not bit and (fill or prev_is_true):
filling.append(top_l_p)
filling.append(Vector2(x, offsetted_size.y - y - 1))
filling.append(Vector2(offsetted_size.x - x - 1, y))
filling.append(Vector2(offsetted_size.x - x - 1, offsetted_size.y - y - 1))
if prev_is_true:
fill = true
prev_is_true = false
elif bit and fill:
break
return PoolVector2Array(border + filling)
return DrawingAlgos.get_ellipse_points_filled(Vector2.ZERO, size, _thickness)
func _get_shape_points(size: Vector2) -> PoolVector2Array: