Add rect / bounding_box to cubic bezier

This commit is contained in:
Alex Clink 2022-02-25 00:38:53 -05:00
parent 6b1f3d0d1c
commit 58e4d59aa8
2 changed files with 39 additions and 25 deletions

View file

@ -31,12 +31,12 @@ module PF
def update(dt, event)
case event
when SDL::Event::MouseButton
if event.pressed? && event.button == 1
@selected_point = @hover_point
end
if event.released? && event.button == 1
@selected_point = nil
if event.button == 1
if event.pressed?
@selected_point = @hover_point
else
@selected_point = nil
end
end
when SDL::Event::MouseMotion
@mouse_pos = Vector[event.x, event.y] // scale
@ -44,8 +44,7 @@ module PF
unless point = @selected_point
@hover_point = @curve.points.find { |p| @mouse_pos.distance(p.value) < 4 }
else
point.value.x = @mouse_pos.x.to_f
point.value.y = @mouse_pos.y.to_f
point.value = @mouse_pos.to_f
end
end
end
@ -57,16 +56,14 @@ module PF
draw_line(@curve.p3, @curve.p2, CTL_COLOR)
draw_string("Length: " + @curve.length.round(2).to_s, 5, 5, FONT_COLOR)
draw_rect(*@curve.rect.map(&.to_i), CTL_COLOR)
draw_curve(@curve, CURVE_COLOR)
ext_x, ext_y = @curve.extremeties
ext_x.each do |point|
draw_circle(point.to_i, 3, EXT_X_COLOR)
end
ext_y.each do |point|
draw_circle(point.to_i, 3, EXT_Y_COLOR)
@curve.extremeties.each do |point|
point.try do |p|
draw_circle(p.to_i, 3, EXT_Y_COLOR)
end
end
fill_circle(@curve.p0.to_i, 2, POINT_COLOR)

View file

@ -24,7 +24,7 @@ module PF
disc = b * b - 4 * a * c
return Tuple.new unless disc >= 0
return {nil, nil} unless disc >= 0
t1 = (-b + Math.sqrt(disc)) / (2 * a)
t2 = (-b - Math.sqrt(disc)) / (2 * a)
@ -35,11 +35,11 @@ module PF
if accept_1 && accept_2
{t1, t2}
elsif accept_1
{t1}
{t1, nil}
elsif accept_2
{t2}
{nil, t2}
else
{0.5}
{0.5, nil}
end
end
@ -80,14 +80,31 @@ module PF
end
# Get the points at the extremeties of this curve
# note: Will return 4 values which are either Float64 | nil
def extremeties
txs = self.class.extremeties(@p0.x, @p1.x, @p2.x, @p3.x)
tys = self.class.extremeties(@p0.y, @p1.y, @p2.y, @p3.y)
exts = self.class.extremeties(@p0.x, @p1.x, @p2.x, @p3.x) +
self.class.extremeties(@p0.y, @p1.y, @p2.y, @p3.y)
exts.map { |e| e ? at(e) : e }
end
txs = txs.map { |t| at(t) }
tys = tys.map { |t| at(t) }
def rect
tl, br = @p0, @p3
{txs, tys}
tl.x = @p3.x if @p3.x < tl.x
tl.y = @p3.y if @p3.y < tl.y
br.x = @p0.x if @p0.x > br.x
br.y = @p0.y if @p0.y > br.y
extremeties.each do |e|
e.try do |e|
tl.x = e.x if e.x < tl.x
tl.y = e.y if e.y < tl.y
br.x = e.x if e.x > br.x
br.y = e.y if e.y > br.y
end
end
{tl, br}
end
end
end