Bezier Curve

Материал из Поле цифровой дидактики

Шаблон:Stub A Bezier Curve is a smooth curve with many control points. It is infinitely scalable and often used in graphics and terrain generation. To make one in Scratch, one must use the following two methods:

Method 1

when green flag clicked
hide
pen up
set pen size to (2)
forever
  erase all
  def p-line :: custom
  set pen color to (#268435)
  draw p-line :: custom
  set pen color to (255)
  draw b-line steps: (90) :: custom
end

define set q-point A: (A.x :: custom-arg) (A.y :: custom-arg) B: (B.x :: custom-arg) (B.y :: custom-arg) progress: (progress :: custom-arg)
set [q.x v] to ((A.x :: custom-arg) + ((progress :: custom-arg) * ((B.x :: custom-arg) - (A.x :: custom-arg))))
set [q.y v] to ((A.y :: custom-arg) + ((progress :: custom-arg) * ((B.y :: custom-arg) - (A.y :: custom-arg))))

define def p-line
delete all of [p.x v]
delete all of [p.y v]
add ([x position v] of [P.00 v]) to [p.x v] // These are all the controls points of the curve, using clones is another solution to this.
add ([y position v] of [P.00 v]) to [p.y v]
add ([x position v] of [P.01 v]) to [p.x v]
add ([y position v] of [P.01 v]) to [p.y v]
add ([x position v] of [P.02 v]) to [p.x v]
add ([y position v] of [P.02 v]) to [p.y v]
add ([x position v] of [P.03 v]) to [p.x v]
add ([y position v] of [P.03 v]) to [p.y v]
add ([x position v] of [P.04 v]) to [p.x v]
add ([y position v] of [P.04 v]) to [p.y v]
add ([x position v] of [P.05 v]) to [p.x v]
add ([y position v] of [P.05 v]) to [p.y v]
add ([x position v] of [P.06 v]) to [p.x v]
add ([y position v] of [P.06 v]) to [p.y v]
add ([x position v] of [P.07 v]) to [p.x v]
add ([y position v] of [P.07 v]) to [p.y v]
add ([x position v] of [P.08 v]) to [p.x v]
add ([y position v] of [P.08 v]) to [p.y v]
add ([x position v] of [P.09 v]) to [p.x v]
add ([y position v] of [P.09 v]) to [p.y v]
add ([x position v] of [P.10 v]) to [p.x v]
add ([y position v] of [P.10 v]) to [p.y v]
add ([x position v] of [P.11 v]) to [p.x v]
add ([y position v] of [P.11 v]) to [p.y v]
add ([x position v] of [P.12 v]) to [p.x v]
add ([y position v] of [P.12 v]) to [p.y v]
add ([x position v] of [P.13 v]) to [p.x v]
add ([y position v] of [P.13 v]) to [p.y v]

define set b-point progress: (progress :: custom-arg)
delete all of [b.x v]
delete all of [b.y v]
repeat (length of [p.x v])
  add (item ((length of [b.x v]) + (1)) of [p.x v]) to [b.x v]
  add (item ((length of [b.y v]) + (1)) of [p.y v]) to [b.y v]
end
set [index.n v] to [1]
repeat ((length of [b.x v]) - (index.n))
  repeat ((length of [b.x v]) - (index.n))
    set q-point A: (item (index.n) of [b.x v]) (item (index.n) of [b.y v]) B: (item ((index.n) + (1)) of [b.x v]) (item ((index.n) + (1)) of [b.y v]) progress: (progress :: custom-arg) :: custom
    add (q.x) to [b.x v]
    add (q.y) to [b.y v]
    change [index.n v] by (1)
  end
  change [index.n v] by (1)
end

define draw p-line
set [loop.n v] to [1]
go to x: (item (loop.n) of [p.x v]) y: (item (loop.n) of [p.y v])
pen down
repeat ((length of [p.x v]) - (loop.n))
  change [loop.n v] by (1)
  go to x: (item (loop.n) of [p.x v]) y: (item (loop.n) of [p.y v])
end
pen up

define draw b-line steps: (steps :: custom-arg)
set [loop.n v] to [0]
set b-point progress: ((loop.n) / (steps :: custom-arg)) :: custom
go to x: (q.x) y: (q.y)
pen down
repeat ((steps :: custom-arg) - (loop.n))
  change [loop.n v] by (1)
  set b-point progress: ((loop.n) / (steps :: custom-arg)) :: custom
  go to x: (q.x) y: (q.y)
end
pen up

Method 2

One sprite needs this:

When green flag clicked
hide
delete all of [clone x v]
delete all of [clone y v]
set drag mode [draggable v]
make clones :: custom

define make clones
set [Clone ID v] to (1) //local variable
repeat (10)
  create clone of [myself v]
  add () to [clone x v]
  add () to [clone y v]
end

When I start as a clone
show//make sure it has a costume
go to (random position v)
forever
  replace item (clone ID) of [clone x v] with (x position)
  replace item (clone ID) of [clone y v] with (y position)
end

In another sprite, put this:

When green flag clicked
forever
  erase all
  draw line between dots :: custom //without screen refresh
  Find curve points :: custom //without screen refresh
end

define copy main points
delete all of [x v]
delete all of [y v]
set [counter v] to (1)
repeat (length of [clone x v])
  add (item (counter) of [clone x v]) to [x v]
  add (item (counter) of [clone y v]) to [y v]
  change [counter v] by (1)
end

define find curve points
delete all of [curve x v]
delete all of [curve y v]
set [t v] to (1)
repeat (100)
  copy main points :: custom
  repeat until <(length of [x v]) = (1)>
    find lines :: custom
  end
  add (x :: list) to [curve x v]
  add (y :: list) to [curve y v]
  change [t v] by (1)
end
Draw curve :: custom

define move (t)% to x: (x) y: (y)
point in direction (([atan v] of (((x position)-(x))/((y position)-(y))))+((180)*<(y position)<(y)>))
move (([sqrt v] of ((((x position)-(x))*((x position)-(x)))+(((y position)-(y))*((y position)-(y)))))*((t)/(100))) steps

define find lines
set [line counter v] to (1)
repeat ((length of [x v])-(1))
  go to x: (item (line counter) of [x v]) y: (item (line counter) of [y v])
  move (t)% to x: (item ((line counter)+(1)) of [x v]) y: (item ((line counter)+(1)) of [y v]) :: custom
  add (x position) to [x v]
  add (y position) to [y v]
  change [line counter v] by (1)
end
repeat ((line counter)-(1))
  delete (1) of [x v]
  delete (1) of [y v]
end

define Draw curve
go to x: (item (1) of [curve x v]) y: (item (1) of [curve y v])
pen down
set [line counter v] to (1)
repeat (length of [curve x v])
  go to x: (item (line counter) of [curve x v]) y: (item (line counter) of [curve y v])
  change [line counter v] by (1)
end
pen up

define draw line between dots
go to x: (item (1) of [clone x v]) y: (item (1) of [clone y v])
pen down
set [line counter v] to (1)
repeat (length of [clone x v])
  go to x: (item (line counter) of [clone x v]) y: (item (line counter) of [clone y v])
  change [line counter v] by (1)
end
pen up


Example located here

Uses of Bezier Curves

There are many uses of Bezier curves within Scratch. These can include:

  • Combining them with velocity to make things fall or bounce.
  • Rendering a terrain with hills so that when one zooms in, the curve still looks nice.
  • Making customisable graphs.

See Also