赞 | 0 |
VIP | 0 |
好人卡 | 1 |
积分 | 1 |
经验 | 2446 |
最后登录 | 2016-9-12 |
在线时间 | 21 小时 |
Lv1.梦旅人
- 梦石
- 0
- 星屑
- 50
- 在线时间
- 21 小时
- 注册时间
- 2011-8-22
- 帖子
- 13
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 lotsofone 于 2013-1-3 21:36 编辑
下面是贝塞尔曲线的代码- class Point
- attr_accessor :x,:y
- def initialize(x,y)
- @x = x ; @y = y
- end
- def +(point)
- return Point.new(@x+point.x,@y+point.y)
- end
- def *(value)
- return Point.new(@x*value,@y*value)
- end
- def -(point)
- return Point.new(@x-point.x,@y-point.y)
- end
- def distance_to(point)
- return Math.sqrt((@x-point.x)**2+(@y-point.y)**2)
- end
- def round
- return Point.new(@x.round, @y.round)
- end
- def to_i
- return Point.new(@x.to_i, @y.to_i)
- end
- end
- class Bitmap
- def simple_draw_line(x1_input, y1_input, x2_input, y2_input,
- color = Color.new(255, 255, 255))
- x1 = x1_input.to_i ; y1 = y1_input.to_i
- x2 = x2_input.to_i ; y2 = y2_input.to_i
- if (x1 - x2).abs >= (y1 - y2).abs #横轴比纵轴长,此时以x为循环变量画线。
- if x1 > x2#保证x1在左边
- c = x1 ; x1 = x2 ; x2 = c ; c = y1 ; y1 = y2 ; y2 = c
- end
- for x in x1..x2#作图
- y = y2*(x - x1).to_f/(x2 - x1) + y1*(x2 - x).to_f/(x2 -x1)
- self.set_pixel(x, y, color)
- end
- else #纵轴比横轴长,此时以y为循环变量画线。
- if y1 > y2 #保证y1在上面
- c = x1 ; x1 = x2 ; x2 = c ; c = y1 ; y1 = y2 ; y2 = c
- end
- for y in y1..y2#作图
- x = x2*(y - y1).to_f/(y2 - y1) + x1*(y2 - y).to_f/(y2 - y1)
- self.set_pixel(x, y, color)
- end
- end
- end
- end
复制代码- class Bezier
- attr_accessor :p1, :p2, :p3, :p4
- def initialize(p1,p2,p3,p4)#p1,p4为端点,p2,p3为控制点
- @p1 = p1 ; @p2 = p2 ; @p3 = p3 ; @p4 = p4
- end
- def show_bezier_sprite(viewport, width = 1, color = Color.new(255, 255, 255))#返回一个精灵显示曲线。
- rx = [p1.x,p2.x,p3.x,p4.x].min
- ry = [p1.y,p2.y,p3.y,p4.y].min
- rw = [p1.x,p2.x,p3.x,p4.x].max
- rh = [p1.y,p2.y,p3.y,p4.y].max
- rh -= ry ; rw -= rx
- w = width/2.0 + 3
- rx -= w ; ry -= w ; rh += 2*w ; rw += 2*w
- rx = rx.to_i ; ry = ry.to_i ; rh = rh.to_i ; rw = rw.to_i
- #整个图形必定限制在矩形rx,ry,rw,rh中
- sprite = Sprite.new(viewport)
- sprite.bitmap = Bitmap.new(rw, rh)
- sprite.x = rx ; sprite.y = ry
- cp1 = @p1 - Point.new(rx, ry)
- cp2 = @p2 - Point.new(rx, ry)
- cp3 = @p3 - Point.new(rx, ry)
- cp4 = @p4 - Point.new(rx, ry)
- #p为以窗口左上角为0点的点,cp为以bitmap左上角为原点的点
- coefficien_a = cp4-cp3*3+cp2*3-cp1
- coefficien_b = cp3*3-cp2*6+cp1*3
- coefficien_c = cp2*3-cp1*3
- coefficien_d = cp1
- lastp = cp1.to_i
- sprite.bitmap.set_pixel(lastp.x, lastp.y, color)
- for n in 1..100#这个数据可更改,数据越大,精度越高。若更改,下面的100.0也要改。
- t = n/100.0
- thisp = (coefficien_a*t**3+coefficien_b*t**2+coefficien_c*t+coefficien_d).to_i
- if thisp.distance_to(lastp) > 1.42 then
- sprite.bitmap.simple_draw_line(lastp.x, lastp.y, thisp.x, thisp.y, color)
- else
- sprite.bitmap.set_pixel(thisp.x, thisp.y, color)
- end
- lastp = thisp
- end
- return sprite
- end
- end
复制代码 运行下列代码,就可以得到一个画上曲线的精灵了。- viewport = Viewport.new(0, 0, 544, 416)
- p1 = Point.new(50, 50)
- p2 = Point.new(50, 400)
- p3 = Point.new(500, 400)
- p4 = Point.new(500, 50)
- bezier = Bezier.new(p1, p2, p3, p4)
- sb = bezier.show_bezier_sprite(viewport, 1, Color.new(0, 255, 0))
复制代码 下面两张图是效果图,数字1 2 3 4和控制点是我自己加的。
可是打开人家coreldraw的曲线一看
那么平滑,我这么粗糙的线怕是拿不出手啊。
如何才能让曲线更平滑呢? |
评分
-
查看全部评分
|