和上文中的公式相同, 但是有一些字母的替换, 表达习惯不同
控制点是独立的, 因此求导是直接对u就行求导, 就是仅仅对参数项B进行求导.
定义: Q0=n*(P1-P0), Q0=n*(P2-P1), Q0=n*(P3-P2),...Qn-1=n*(Pn-Pn-1), . 如果我们把Q当做一组新的控制点, 那么原贝塞尔的导数可以写成如下:
导数还是贝塞尔曲线, 只不过是控制点是原来控制点的组合而已.
以下是一个三阶贝塞尔曲线golang例子:
package main
import(
"fmt"
"image"
"image/color"
"image/png"
"log"
"os"
)
// Putpixel describes a function expected to draw a point on a bitmap at (x, y) coordinates.
type Putpixel func(x, y int)
func drawline(x0, y0, x3, y3 int, brush Putpixel) {
x1 := 500
y1 := 500
x2 := 0
y2 := 250
for i := 0; i < 1000; i++ {
t := float32(i) / 1000.0
x := int((1.0 - t) * (1.0 - t) * (1.0 - t) * float32(x0) + 3.0 * t * (1 - t) * (1 - t) * float32(x1) + 3.0 * t * t * (1 - t) * float32(x2) + t * t * t * float32(x3))
y := int((1.0 - t) * (1.0 - t) * (1.0 - t) * float32(y0) + 3.0 * t * (1 - t) * (1 - t) * float32(y1) + 3.0 * t * t * (1 - t) * float32(y2) + t * t * t * float32(y3))
brush(x,y)
}
}
func main() {
dx := 500
dy := 500
img := image.NewNRGBA(image.Rect(0, 0, dx, dy))
drawline(350, 250, 500, 250, func(x, y int) {
img.Set(x, y, color.Black)
})
// 左右都画一条竖线
for i := 0; i < dy; i++ {
img.Set(0, i, color.Black)
img.Set(dx - 1, i, color.Black)
}
imgcounter := 250
imgfile, _ := os.Create(fmt.Sprintf("%03d.png", imgcounter))
defer imgfile.Close()
// 以PNG格式保存文件
err := png.Encode(imgfile, img)
if err != nil{
log.Fatal(err)
}
}