设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2714|回复: 11
打印 上一主题 下一主题

[原创发布] 【正式发布】RM BitmapCanvas 2D绘图插件

[复制链接]

Lv5.捕梦者 (版主)

遠航の猫咪

梦石
3
星屑
23209
在线时间
2387 小时
注册时间
2005-10-15
帖子
1166

开拓者

跳转到指定楼层
1
发表于 2022-11-21 06:13:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
不依赖SEP,插入默认工程应该就可以使用
提供20个绘图指令,无论如何应该够用了

Q&A:
Q:这个脚本能用来干什么?
A:绘制异型血槽(如环状)、绘制能力雷达(六边形战士)、绘制渐变转场中的渐变分隔线、异型透视窗格、等等……
Q:绘图指令具体如何调用?
A:参见脚本前面的说明。
Q:能用虚线绘制矩形和直线以外的形状吗?
A:不能。
Q:为什么可填充的形状中不包括矩形?
A:参见Bitmap#fill_rect,如果你使用RGD或者SEP Core那么还有Bitmap#gradient_fill_rect
Q:我想用平行四边形切一个位图传送怎么办?默认只有Bitmap#blt,而你这个插件也只能用正多边形切正方形或者菱形?
A:请找到四边形的四个顶点,然后调用blt_polygon,所有平行四边形都是多边形的一种。
Q:我的位图传送后被切边了,不完整?
A:只有用位图填充,即fill系指令时,你给的位图会被插件自动重复成图案以保证填满。仅单纯的传送不会复制位图,如果你的位图比传送的区域小,尝试使用填充指令而不是传送指令,或者你看看是不是参照点没有写对导致传歪了。
Q:渐变的效率怎么样?
A:肯定是不如GDI+,但是比draw_text快,反正你用足够了。

RUBY 代码复制
  1. #==============================================================================
  2. # ■ [Bitmap Canvas] 位图画布处理核心 v1.1 by SailCat
  3. #------------------------------------------------------------------------------
  4. #   方法:本脚本插入Main之前使用
  5. #   依赖:无
  6. #   版本:v1.1 (Build 221121)
  7. #   效果:
  8. #     1. 可以用简单指令在位图对象上绘制图形,可以绘制从直线到封闭曲线的15种图形
  9. #     2. 可以用简单指令在位图对象上叠加以不同形状(共5种)剪裁的其他位图
  10. #   配置:画笔线形的配置
  11. #   冲突:无
  12. #   说明:
  13. #     1. 绘制直线:
  14. #        draw_line(起始x, 起始y, 结束x, 结束y, 颜色, 线形)
  15. #     2. 绘制矩形(空心):
  16. #       a) draw_rect(左上x, 左上y, 长, 宽, 颜色, 线形)
  17. #       b) draw_rect(矩形, 颜色, 线形)
  18. #     3. 绘制渐变色直线:
  19. #        gradient_draw_line(起始x, 起始y, 结束x, 结束y, 颜色1, 颜色2)
  20. #     4. 绘制路径(连续直线):
  21. #        draw_path(点1x, 点1y, 点2x, 点2y, 点3x, 点3y[, ...], 颜色)
  22. #     5. 绘制多边形(连续封闭直线):
  23. #        draw_polygon(点1x, 点1y, 点2x, 点2y, 点3x, 点3y[, ...], 颜色)
  24. #     6. 绘制正多边形:
  25. #        draw_isogon(外接圆心x, 外接圆心y, 半径, 边数, 旋转角, 颜色)
  26. #     7. 绘制椭圆:
  27. #        draw_ellipse(圆心x, 圆心y, 半横径,半纵径, 颜色)
  28. #     8. 绘制圆:
  29. #        draw_circle(圆心x, 圆心y, 半径,颜色)
  30. #     9. 绘制曲线:
  31. #        draw_curve(起始x, 起始y, 中继点Ax, 中继点Ay, 中继点Bx, 中继点By[,
  32. #          中继点Cx, 中继点Cy[, ...]], 结束x, 结束y, 颜色)
  33. #     10. 绘制封闭曲线:
  34. #        draw_closed_curve(点1x, 点1y, 中继1Ax, 中继1Ay, 中继1Bx, 中继1By,
  35. #          点2x, 点2y[, 中继2Ax, 中继2Ay, 中继2Bx, 中继2By, 点3x, 点3y[, ...]],
  36. #          颜色)
  37. #     11.填涂多边形:
  38. #       a) fill_polygon(点1x, 点1y, 点2x, 点2y, 点3x, 点3y[, ...], 边框颜色[,
  39. #          填充颜色1[, 填充颜色2[, 渐变方向]]])
  40. #       b) fill_polygon(点1x, 点1y, 点2x, 点2y, 点3x, 点3y[, ...], 边框颜色,
  41. #          填充位图[, 不透明度])
  42. #     12.填涂正多边形:
  43. #       a) fill_isogon(外接圆心x, 外接圆心y, 半径, 边数, 旋转角, 边框颜色[,
  44. #          填充颜色1[, 填充颜色2[, 渐变方向]]])
  45. #       b) fill_isogon(外接圆心x, 外接圆心y, 半径, 边数, 旋转角, 边框颜色,
  46. #          填充位图[, 不透明度])
  47. #     13.填涂椭圆:
  48. #       a) fill_ellipse(圆心x, 圆心y, 半横径,半纵径, 边框颜色[, 填充颜色1[,
  49. #          填充颜色2[, 渐变方向]]])
  50. #       b) fill_ellipse(圆心x, 圆心y, 半横径,半纵径, 边框颜色, 填充位图[,
  51. #          不透明度])
  52. #     14.填涂圆:
  53. #       a) fill_circle(圆心x, 圆心y, 半径,边框颜色[, 填充颜色1[, 填充颜色2[,
  54. #          渐变方向]]])
  55. #       b) fill_circle(圆心x, 圆心y, 半径,边框颜色, 填充位图[, 不透明度])
  56. #     15.填涂封闭曲线:
  57. #       a) fill_closed_curve(点1x, 点1y, 中继1Ax, 中继1Ay, 中继1Bx, 中继1By,
  58. #          点2x, 点2y[, 中继2Ax, 中继2Ay, 中继2Bx, 中继2By, 点3x, 点3y[, ...]],
  59. #          边框颜色[, 填充颜色1[, 填充颜色2[, 渐变方向]]])
  60. #       b) fill_closed_curve(点1x, 点1y, 中继1Ax, 中继1Ay, 中继1Bx, 中继1By,
  61. #          点2x, 点2y[, 中继2Ax, 中继2Ay, 中继2Bx, 中继2By, 点3x, 点3y[, ...]],
  62. #          边框颜色, 填充位图[, 不透明度])
  63. #     16.传送多边形:
  64. #        blt_polygon(点1x, 点1y, 点2x, 点2y, 点3x, 点3y[, ...], 源位图,
  65. #          参考点1x, 参考点1y[, 不透明度])
  66. #     17.传送正多边形:
  67. #        blt_isogon(外接圆心x, 外接圆心y, 半径, 边数, 旋转角, 源位图, 参考心x,
  68. #          参考心y[, 不透明度])
  69. #     18.传送椭圆:
  70. #        blt_ellipse(圆心x, 圆心y, 半横径,半纵径, 源位图, 参考心x, 参考心y[,
  71. #          不透明度])
  72. #     19.传送圆:
  73. #        blt_circle(圆心x, 圆心y, 半径,源位图, 参考心x, 参考心y[, 不透明度])
  74. #     20.传送封闭曲线:
  75. #        blt_closed_curve(点1x, 点1y, 中继1Ax, 中继1Ay, 中继1Bx, 中继1By,
  76. #          点2x, 点2y[, 中继2Ax, 中继2Ay, 中继2Bx, 中继2By, 点3x, 点3y[, ...]],
  77. #          源位图, 参考点1x, 参考点1y[, 不透明度])
  78. #==============================================================================
  79. #==============================================================================
  80. # ■ SailCat's 插件公用
  81. #==============================================================================
  82. module SailCat
  83.   #--------------------------------------------------------------------------
  84.   # ● 脚本配置区
  85.   #--------------------------------------------------------------------------
  86.   module Canvas_Config
  87.     CANVAS_LINE_DOTTED = [1, 0]               # 点线画笔
  88.     CANVAS_LINE_DASHED = [1, 1, 0, 1]         # 短虚线画笔
  89.     CANVAS_LINE_LONGDASH = [1, 1, 0, 0, 1, 1] # 长虚线画笔
  90.     CANVAS_LINE_DASHDOT = [1, 0, 1, 1, 1, 0]  # 点划线画笔
  91.     CANVAS_LINE_BROKEN = [1, 0, 0]            # 散点画笔
  92.   end
  93. end
  94.  
  95. #==============================================================================
  96. # ■ Bitmap
  97. #==============================================================================
  98. class Bitmap
  99.   include SailCat::Canvas_Config
  100.   #--------------------------------------------------------------------------
  101.   # ● 常量
  102.   #--------------------------------------------------------------------------
  103.   CANVAS_LINE_SOLID = [1]                     # 实心画笔,该常量禁止修改配置
  104.   #--------------------------------------------------------------------------
  105.   # ● 绘制直线
  106.   #     x1 : 起始的 X 坐标
  107.   #     y1 : 起始的 Y 坐标
  108.   #     x2 : 结束的 X 坐标
  109.   #     y2 : 结束的 Y 坐标
  110.   #     color : 直线的颜色 (Color)
  111.   #     style : 直线的线型
  112.   #--------------------------------------------------------------------------
  113.   def draw_line(x1, y1, x2, y2, color, style = CANVAS_LINE_SOLID)
  114.     return set_pixel(x1, y1, color) if x1 == x2 and y1 == y2
  115.     dx = (x2 - x1).abs
  116.     dy = (y2 - y1).abs
  117.     x = x1
  118.     y = y1
  119.     rx = x2 - x1 <=> 0
  120.     ry = y2 - y1 <=> 0
  121.     b_index = 0
  122.     b_size = style.size
  123.     if dx == 0 and style == CANVAS_LINE_SOLID
  124.       fill_rect(x1, [y1, y2].min, 1, dy + 1, color)
  125.     elsif dy == 0 and style == CANVAS_LINE_SOLID
  126.       fill_rect([x1, x2].min, y1, dx + 1, 1, color)
  127.     elsif dx <= dy
  128.       f = dx.to_f * rx / dy
  129.       dy.times do
  130.         set_pixel(x.round, y, color) if style[b_index] == 1
  131.         x += f
  132.         y += ry
  133.         b_index = (b_index + 1) % b_size
  134.       end
  135.       set_pixel(x.round, y, color)
  136.     else
  137.       f = dy.to_f * ry / dx
  138.       dx.times do
  139.         set_pixel(x, y.round, color) if style[b_index] == 1
  140.         x += rx
  141.         y += f
  142.         b_index = (b_index + 1) % b_size
  143.       end
  144.       set_pixel(x, y.round, color)
  145.     end
  146.   end
  147.   #--------------------------------------------------------------------------
  148.   # ● 绘制空心矩形
  149.   #     参数形式1 : 左上 X 坐标, 左上 Y 坐标, 宽度, 高度, 颜色, 线型
  150.   #     参数形式2 : 目标矩形 (Rect), 颜色, 线型
  151.   #--------------------------------------------------------------------------
  152.   def draw_rect(*args)
  153.     case args[0]
  154.     when Numeric
  155.       raise ArgumentError if args.size < 4
  156.       x, y, w, h, color = args[0..4]
  157.       style = args[5] || CANVAS_LINE_SOLID
  158.     when Rect
  159.       raise ArgumentError if args.size < 2
  160.       rect = args[0]
  161.       x, y, w, h = rect.x, rect.y, rect.width, rect.height
  162.       color = args[1]
  163.       style = args[2] || CANVAS_LINE_SOLID
  164.     else
  165.       raise ArgumentError
  166.     end
  167.     draw_line(x, y, x + w, y, color, style)
  168.     draw_line(x, y, x, y + h, color, style)
  169.     draw_line(x + w, y, x + w, y + h, color, style)
  170.     draw_line(x, y + h, x + w, y + h, color, style)
  171.   end
  172.   #--------------------------------------------------------------------------
  173.   # ● 绘制渐变直线
  174.   #     x1 : 起始的 X 坐标
  175.   #     y1 : 起始的 Y 坐标
  176.   #     x2 : 结束的 X 坐标
  177.   #     y2 : 结束的 Y 坐标
  178.   #     color1 : 直线的起始颜色 (Color)
  179.   #     color2 : 直线的终止颜色 (Color)
  180.   #--------------------------------------------------------------------------
  181.   def gradient_draw_line(x1, y1, x2, y2, color1, color2)
  182.     return set_pixel(x1, y1, color) if x1 == x2 and y1 == y2
  183.     return draw_line(x1, y1, x2, y2, color1) if color1 == color2
  184.     dx = (x2 - x1).abs
  185.     dy = (y2 - y1).abs
  186.     rx = x2 - x1 <=> 0
  187.     ry = y2 - y1 <=> 0
  188.     c = color1.clone
  189.     if dx <= dy
  190.       f = dx.to_f / dy * rx
  191.       x = x1.to_f
  192.       y = y1
  193.       dr = (color2.red - color1.red) / dy
  194.       dg = (color2.green - color1.green) / dy
  195.       db = (color2.blue - color1.blue) / dy
  196.       da = (color2.alpha - color1.alpha) / dy
  197.       (dy + 1).times do
  198.         set_pixel(x.round, y, c)
  199.         x += f
  200.         y += ry
  201.         c.set(c.red + dr, c.green + dg, c.blue + db, c.alpha + da)
  202.       end
  203.     else
  204.       f = dy.to_f / dx * ry
  205.       x = x1
  206.       y = y1.to_f
  207.       dr = (color2.red - color1.red) / dx
  208.       dg = (color2.green - color1.green) / dx
  209.       db = (color2.blue - color1.blue) / dx
  210.       da = (color2.alpha - color1.alpha) / dx
  211.       (dx + 1).times do
  212.         set_pixel(x, y.round, c)
  213.         x += rx
  214.         y += f
  215.         c.set(c.red + dr, c.green + dg, c.blue + db, c.alpha + da)
  216.       end
  217.     end
  218.   end
  219.   #--------------------------------------------------------------------------
  220.   # ● 绘制路径
  221.   #     x1 : 第一点的 X 坐标
  222.   #     y1 : 第一点的 Y 坐标
  223.   #     x2 : 第二点的 X 坐标
  224.   #     y2 : 第二点的 Y 坐标
  225.   #     x3 : 第三点的 X 坐标
  226.   #     y3 : 第三点的 Y 坐标
  227.   #     args : 后续的参数(可以加多个点,至少要包括颜色)
  228.   #--------------------------------------------------------------------------
  229.   def draw_path(x1, y1, x2, y2, x3, y3, *args)
  230.     raise ArgumentError if args.size[0] == 0 or not args[-1].is_a?(Color)
  231.     color = args[-1]
  232.     nodes = [x1, y1, x2, y2, x3, y3].concat(args[0...-1])
  233.     0.step(nodes.size - 4, 2) {|i| draw_line(*(nodes[i, 4].concat([color])))}
  234.   end
  235.   #--------------------------------------------------------------------------
  236.   # ● 绘制多边形
  237.   #     x1 : 第一点的 X 坐标
  238.   #     y1 : 第一点的 Y 坐标
  239.   #     x2 : 第二点的 X 坐标
  240.   #     y2 : 第二点的 Y 坐标
  241.   #     x3 : 第三点的 X 坐标
  242.   #     y3 : 第三点的 Y 坐标
  243.   #     args : 后续的参数(可以加多个点,至少要包括颜色)
  244.   #--------------------------------------------------------------------------
  245.   def draw_polygon(x1, y1, x2, y2, x3, y3, *args)
  246.     raise ArgumentError if args.size[0] == 0 or not args[-1].is_a?(Color)
  247.     args.insert(-2, x1, y1)
  248.     draw_path(x1, y1, x2, y2, x3, y3, *args)
  249.   end
  250.   #--------------------------------------------------------------------------
  251.   # ● 绘制实心多边形
  252.   #     x1 : 第一点的 X 坐标
  253.   #     y1 : 第一点的 Y 坐标
  254.   #     x2 : 第二点的 X 坐标
  255.   #     y2 : 第二点的 Y 坐标
  256.   #     x3 : 第三点的 X 坐标
  257.   #     y3 : 第三点的 Y 坐标
  258.   #     args : 后续的参数,包括后续点,并在所有点之后指定填充选项,填充选项有:
  259.   #            3个颜色 + true/false : 颜色1为边框色,颜色2和颜色3用于填充,最后
  260.   #              true = 垂直方向渐变 false = 水平方向渐变
  261.   #            3个颜色 : 颜色1用于描边,颜色2和颜色3用于填充,固定水平方向渐变
  262.   #            2个颜色 : 颜色1用于描边,颜色2用于填充
  263.   #            1个颜色 : 以该颜色描边,并实心填充
  264.   #            颜色 + 位图 + 数值 : 颜色用于描边,位图用于填充,数值为不透明度
  265.   #            颜色 + 位图 : 颜色用于描边,位图用于填充,不透明度固定为255
  266.   #--------------------------------------------------------------------------
  267.   def fill_polygon(x1, y1, x2, y2, x3, y3, *args)
  268.     case args[-1]
  269.     when FalseClass, TrueClass
  270.       raise ArgumentError unless args[-4..-2].all?{|c| c.is_a?(Color)}
  271.       fill_mode = args.pop ? 1 : 0
  272.       fill2 = args.pop
  273.       fill1 = args.pop
  274.       fill_mode = 0 if fill1 == fill2
  275.     when Color
  276.       fill_mode = 0
  277.       fill2 = args[-3].is_a?(Color) ? args.pop : args[-1]
  278.       fill1 = args[-2].is_a?(Color) ? args.pop : args[-1]
  279.     when Bitmap
  280.       raise ArgumentError unless args[-2].is_a?(Color)
  281.       fill_mode = 2
  282.       fill_opacity = 255
  283.       fill_pattern = args.pop
  284.     when Numeric
  285.       raise ArgumentError unless args[-3].is_a?(Color) and
  286.         args[-2].is_a?(Bitmap)
  287.       fill_mode = 2
  288.       fill_opacity = args.pop
  289.       fill_pattern = args.pop
  290.     else
  291.       raise ArgumentError
  292.     end
  293.     draw_polygon(x1, y1, x2, y2, x3, y3, *args)
  294.     color = args[-1]
  295.     nodes = [x1, y1, x2, y2, x3, y3].concat(args[0...-1])
  296.     edges = {}
  297.     min_y = height
  298.     max_x = max_y = 0
  299.     min_x = width
  300.     0.step(nodes.size - 2, 2) do |i|
  301.       xi, yi = nodes[i, 2]
  302.       min_y = [min_y, yi].min
  303.       max_y = [max_y, yi].max
  304.       min_x = [min_x, xi].min
  305.       max_x = [max_x, xi].max
  306.       xj, yj = nodes[(i + 2) % nodes.size, 2]
  307.       dx = 1.0 * (xi - xj) / (yi - yj)
  308.       if yi < yj
  309.         delta = -1
  310.         delta -= 2 until (yh = nodes[(i + delta) % nodes.size]) != yi
  311.         if yh < yi
  312.           yi += 1
  313.           xi += dx
  314.         end
  315.         edges[yi] ||= []
  316.         edges[yi].push([xi, dx, yj])
  317.       elsif yi > yj
  318.         delta = 5
  319.         delta += 2 until (yk = nodes[(i + delta) % nodes.size]) != yj
  320.         if yj > yk
  321.           yj += 1
  322.           xj += dx
  323.         end
  324.         edges[yj] ||= []
  325.         edges[yj].push([xj, dx, yi])
  326.       end
  327.     end
  328.     return unless max_y - min_y > 1 and max_x - min_x > 1
  329.     dw = max_x - min_x - 1
  330.     dh = max_y - min_y - 1
  331.     if fill_mode == 0
  332.       if fill1 != fill2
  333.         dr = (fill2.red - fill1.red) / dh
  334.         dg = (fill2.green - fill1.green) / dh
  335.         db = (fill2.blue - fill1.blue) / dh
  336.         da = (fill2.alpha - fill1.alpha) / dh
  337.         gradient = true
  338.       end
  339.       f = fill1.clone
  340.       aet = edges[min_y].each {|edge| edge[0] += edge[1]}.sort!
  341.       for y in min_y + 1..max_y - 1
  342.         aet.concat(edges[y]).sort! if edges[y]
  343.         0.step(aet.size - 2, 2) do |i|
  344.           xi = aet[i][0].round
  345.           xj = aet[i + 1][0].round
  346.           xi += 1 until xi == width - 1 or get_pixel(xi, y) != color
  347.           xj -= 1 until xj == 0 or get_pixel(xj, y) != color
  348.           fill_rect(xi, y, xj - xi + 1, 1, f) if xj >= xi
  349.         end
  350.         aet.reject! {|edge| edge[2] == y}
  351.         aet.each {|edge| edge[0] += edge[1]}.sort!
  352.         f.set(f.red + dr, f.green + dg, f.blue + db, f.alpha + da) if gradient
  353.       end
  354.     else
  355.       if fill_mode == 2
  356.         src = Bitmap.new(dw, fill_pattern.height)
  357.         0.step(dw - 1, fill_pattern.width) do |x|
  358.           src.blt(x, 0, fill_pattern, fill_pattern.rect, fill_opacity)
  359.         end
  360.       else
  361.         src = Bitmap.new(dw, 1)
  362.         src.gradient_draw_line(0, 0, dw - 1, 0, fill1, fill2)
  363.       end
  364.       ox = -1 - min_x
  365.       y_index = 0
  366.       aet = edges[min_y].each {|edge| edge[0] += edge[1]}.sort!
  367.       for y in min_y + 1..max_y - 1
  368.         aet.concat(edges[y]).sort! if edges[y]
  369.         0.step(aet.size - 2, 2) do |i|
  370.           xi = aet[i][0].round
  371.           xj = aet[i + 1][0].round
  372.           xi += 1 until xi == width - 1 or get_pixel(xi, y) != color
  373.           xj -= 1 until xj == 0 or get_pixel(xj, y) != color
  374.           blt(xi, y, src, Rect.new(xi + ox, y_index, xj - xi + 1, 1))
  375.         end
  376.         aet.reject! {|edge| edge[2] == y}
  377.         aet.each {|edge| edge[0] += edge[1]}.sort!
  378.         y_index = (y_index + 1) % src.height
  379.       end
  380.       src.dispose
  381.     end
  382.   end
  383.   #--------------------------------------------------------------------------
  384.   # ● 传送位图多边形
  385.   #     x1 : 第一点的 X 坐标
  386.   #     y1 : 第一点的 Y 坐标
  387.   #     x2 : 第二点的 X 坐标
  388.   #     y2 : 第二点的 Y 坐标
  389.   #     x3 : 第三点的 X 坐标
  390.   #     y3 : 第三点的 Y 坐标
  391.   #     args : 后续的参数(加多个点,最后是位图, 偏移x,偏移y,(可选)不透明度)
  392.   #            偏移x和偏移y的位置参考第一个点
  393.   #--------------------------------------------------------------------------
  394.   def blt_polygon(x1, y1, x2, y2, x3, y3, *args)
  395.     if args[-3].is_a?(Bitmap)
  396.       src, x0, y0 = args[-3, 3]
  397.       opacity = 255
  398.       nodes = [x1, y1, x2, y2, x3, y3].concat(args[0...-3])
  399.     elsif args[-4].is_a?(Bitmap)
  400.       src, x0, y0, opacity = args[-4, 4]
  401.       nodes = [x1, y1, x2, y2, x3, y3].concat(args[0...-4])
  402.     else
  403.       raise ArgumentError
  404.     end
  405.     raise ArgumentError unless nodes.size[0] == 0
  406.     edges = {}
  407.     min_y = height
  408.     max_y = 0
  409.     ox = x0 - x1
  410.     oy = y0 - y1
  411.     0.step(nodes.size - 2, 2) do |i|
  412.       xi, yi = nodes[i, 2]
  413.       min_y = [min_y, yi].min
  414.       max_y = [max_y, yi].max
  415.       xj, yj = nodes[(i + 2) % nodes.size, 2]
  416.       dx = 1.0 * (xi - xj) / (yi - yj)
  417.       if yi < yj
  418.         delta = -1
  419.         delta -= 2 until (yh = nodes[(i + delta) % nodes.size]) != yi
  420.         if yh < yi
  421.           yi += 1
  422.           xi += dx
  423.         end
  424.         edges[yi] ||= []
  425.         edges[yi].push([xi, dx, yj])
  426.       elsif yi > yj
  427.         delta = 5
  428.         delta += 2 until (yk = nodes[(i + delta) % nodes.size]) != yj
  429.         if yj > yk
  430.           yj += 1
  431.           xj += dx
  432.         end
  433.         edges[yj] ||= []
  434.         edges[yj].push([xj, dx, yi])
  435.       end
  436.     end
  437.     aet = []
  438.     for y in min_y..max_y
  439.       aet.concat(edges[y]).sort! if edges[y]
  440.       0.step(aet.size - 1, 2) do |i|
  441.         xi = aet[i][0].round
  442.         xj = aet[i + 1][0].round
  443.         blt(xi, y, src, Rect.new(xi + ox, y + oy, xj - xi + 1, 1), opacity)
  444.       end
  445.       aet.reject! {|edge| edge[2] == y}
  446.       aet.each {|edge| edge[0] += edge[1]}.sort!
  447.     end
  448.   end
  449.   #--------------------------------------------------------------------------
  450.   # ● 绘制正多边形
  451.   #     x : 正多边形外接圆心 X 坐标
  452.   #     y : 正多边形外接圆心 Y 坐标
  453.   #     rad : 正多边形外接圆 半径
  454.   #     edges : 正多边形的边数
  455.   #     angle : 正多边形旋转角度
  456.   #     color : 正多边形的颜色 (Color)
  457.   #--------------------------------------------------------------------------
  458.   def draw_isogon(x, y, rad, edges, angle, color)
  459.     raise ArgumentError if edges < 3
  460.     step = Math::PI * 2 / edges
  461.     args = []
  462.     angle_i = Math::PI * (270 + angle) / 180
  463.     edges.times do
  464.       args.push((x + rad * Math.cos(angle_i)).round,
  465.         (y + rad * Math.sin(angle_i)).round)
  466.       angle_i += step
  467.     end
  468.     draw_polygon(*args.push(color))
  469.   end
  470.   #--------------------------------------------------------------------------
  471.   # ● 绘制实心正多边形
  472.   #     x : 正多边形外接圆心 X 坐标
  473.   #     y : 正多边形外接圆心 Y 坐标
  474.   #     rad : 正多边形外接圆 半径
  475.   #     edges : 正多边形的边数
  476.   #     angle : 正多边形旋转角度
  477.   #     color : 边框的颜色 (Color)
  478.   #     fill : 填充选项,具体的填充选项有:
  479.   #            2个颜色 + true/false : 两个颜色以垂直/水平方式渐变填充
  480.   #            2个颜色 : 两个颜色以水平方向渐变填充
  481.   #            1个颜色 : 实心填充
  482.   #            位图 + 数值 : 以位图图案填充,数值为不透明度
  483.   #            位图 : 以位图图案填充,不透明度固定为255
  484.   #            省略 : 用边框色实心填充
  485.   #--------------------------------------------------------------------------
  486.   def fill_isogon(x, y, rad, edges, angle, color, *fill)
  487.     raise ArgumentError if edges < 3
  488.     step = Math::PI * 2 / edges
  489.     args = []
  490.     angle_i = Math::PI * (270 + angle) / 180
  491.     edges.times do
  492.       args.push((x + rad * Math.cos(angle_i)).round,
  493.         (y + rad * Math.sin(angle_i)).round)
  494.       angle_i += step
  495.     end
  496.     fill_polygon(*args.push(color).concat(fill))
  497.   end
  498.   #--------------------------------------------------------------------------
  499.   # ● 传送位图正多边形
  500.   #     x : 正多边形外接圆心 X 坐标
  501.   #     y : 正多边形外接圆心 Y 坐标
  502.   #     rad : 正多边形外接圆 半径
  503.   #     edges : 正多边形的边数
  504.   #     angle : 正多边形旋转角度
  505.   #     src_bitmap : 传送元位图
  506.   #     x0 : 传送圆心 X 坐标
  507.   #     y0 : 传送圆心 Y 坐标
  508.   #     opacity : 不透明度
  509.   #--------------------------------------------------------------------------
  510.   def blt_isogon(x, y, rad, edges, angle, src_bitmap, x0, y0, opacity = 255)
  511.     raise ArgumentError if edges < 3
  512.     step = Math::PI * 2 / edges
  513.     args = []
  514.     angle_i = Math::PI * (270 + angle) / 180
  515.     edges.times do
  516.       args.push((x + rad * Math.cos(angle_i)).round,
  517.         (y + rad * Math.sin(angle_i)).round)
  518.       angle_i += step
  519.     end
  520.     args.push(src_bitmap, x0 - x + args[0], y0 - y + args[1], opacity)
  521.     blt_polygon(*args)
  522.   end
  523.   #--------------------------------------------------------------------------
  524.   # ● 绘制圆
  525.   #     x : 圆心 X 坐标
  526.   #     y : 圆心 Y 坐标
  527.   #     rad : 半径
  528.   #     color : 圆的颜色 (Color)
  529.   #--------------------------------------------------------------------------
  530.   def draw_circle(x, y, rad, color)
  531.     draw_ellipse(x, y, rad, rad, color)
  532.   end
  533.   #--------------------------------------------------------------------------
  534.   # ● 绘制椭圆
  535.   #     x : 圆心 X 坐标
  536.   #     y : 圆心 Y 坐标
  537.   #     rad_x : 水平半径
  538.   #     rad_y : 垂直半径
  539.   #     color : 椭圆的颜色 (Color)
  540.   #--------------------------------------------------------------------------
  541.   def draw_ellipse(x, y, rad_x, rad_y, color)
  542.     fill_ellipse(x, y, rad_x, rad_y, color, nil)
  543.   end
  544.   #--------------------------------------------------------------------------
  545.   # ● 绘制实心圆
  546.   #     x : 圆心 X 坐标
  547.   #     y : 圆心 Y 坐标
  548.   #     rad : 半径
  549.   #     border_color : 圆的边框颜色 (Color)
  550.   #     fill : 填充选项,具体的填充选项有:
  551.   #            nil : 不填充
  552.   #            2个颜色 + true/false : 两个颜色以垂直/水平方式渐变填充
  553.   #            2个颜色 : 两个颜色以水平方向渐变填充
  554.   #            1个颜色 : 实心填充
  555.   #            位图 + 数值 : 以位图图案填充,数值为不透明度
  556.   #            位图 : 以位图图案填充,不透明度固定为255
  557.   #            省略 : 用边框色实心填充
  558.   #--------------------------------------------------------------------------
  559.   def fill_circle(x, y, rad, border_color, *fill)
  560.     fill_ellipse(x, y, rad, rad, border_color, *fill)
  561.   end
  562.   #--------------------------------------------------------------------------
  563.   # ● 绘制实心椭圆
  564.   #     x : 圆心 X 坐标
  565.   #     y : 圆心 Y 坐标
  566.   #     rad_x : 水平半径
  567.   #     rad_y : 垂直半径
  568.   #     border_color : 椭圆的边框颜色 (Color)
  569.   #     fill : 填充选项,具体的填充选项有:
  570.   #            nil : 不填充
  571.   #            2个颜色 + true/false : 两个颜色以垂直/水平方式渐变填充
  572.   #            2个颜色 : 两个颜色以水平方向渐变填充
  573.   #            1个颜色 : 实心填充
  574.   #            位图 + 数值 : 以位图图案填充,数值为不透明度
  575.   #            位图 : 以位图图案填充,不透明度固定为255
  576.   #            省略 : 用边框色实心填充
  577.   #--------------------------------------------------------------------------
  578.   def fill_ellipse(x, y, rad_x, rad_y, border_color, *fill)
  579.     raise ArgumentError if rad_x < 0 or rad_y < 0
  580.     return set_pixel(x, y, border_color) if rad_x == 0 and rad_y == 0
  581.     return fill_rect(x - rad_x, y, rad_x << 1, 1, border_color) if rad_y == 0
  582.     return fill_rect(x, y - rad_y, 1, rad_y << 1, border_color) if rad_x == 0
  583.     ry2 = rad_y * rad_y
  584.     rx2 = rad_x * rad_x
  585.     d = ry2 + rx2 * (0.25 - rad_y)
  586.     dx = 0
  587.     dy = rad_y
  588.     if fill.size == 0
  589.       fill_mode = 0
  590.       f1 = f2 = border_color.clone
  591.     else
  592.       case fill[0]
  593.       when Color
  594.         f1 = fill[0].clone
  595.         if fill[1]
  596.           f2 = fill[1].clone
  597.           fill_mode = f1 == f2 ? 0 : (fill[2] ? 3 : 1)
  598.         else
  599.           f2 = f1
  600.           fill_mode = 0
  601.         end
  602.       when Bitmap
  603.         fill_mode = 2
  604.       else
  605.         fill_mode = -1
  606.       end
  607.     end
  608.     case fill_mode
  609.     when 1
  610.       dist = rad_y - 1 << 1
  611.       if dist > 0
  612.         dr = (f2.red - f1.red) / dist
  613.         dg = (f2.green - f1.green) / dist
  614.         db = (f2.blue - f1.blue) / dist
  615.         da = (f2.alpha - f1.alpha) / dist
  616.       end
  617.     when 2
  618.       src = Bitmap.new((rad_x << 1) - 1, fill[0].height)
  619.       0.step((rad_x << 1) - 1, fill[0].width) do |x0|
  620.         src.blt(x0, 0, fill[0], fill[0].rect, fill[1] || 255)
  621.       end
  622.     when 3
  623.       src = Bitmap.new((rad_x << 1) - 1, 1)
  624.       src.gradient_draw_line(0, 0, rad_x - 1 << 1 , 0, f1, f2)
  625.     end
  626.     begin
  627.       set_pixel(x + dx, y + dy, border_color)
  628.       set_pixel(x + dx, y - dy, border_color)
  629.       set_pixel(x - dx, y - dy, border_color)
  630.       set_pixel(x - dx, y + dy, border_color)
  631.       if d <= -1e-6
  632.         d += ry2 * ((dx << 1) + 3)
  633.       else
  634.         d += ry2 * ((dx << 1) + 3) + rx2 * (1 - dy << 1)
  635.         dy -= 1
  636.         case fill_mode
  637.         when 0, 1
  638.           fill_rect(x - dx, y - dy, (dx << 1) + 1, 1, f1)
  639.           fill_rect(x - dx, y + dy, (dx << 1) + 1, 1, f2)
  640.           if fill_mode == 1
  641.             f1.set(f1.red + dr, f1.green + dg, f1.blue + db, f1.alpha + da)
  642.             f2.set(f2.red - dr, f2.green - dg, f2.blue - db, f2.alpha - da)
  643.           end
  644.         when 2, 3
  645.           blt(x - dx, y - dy, src, Rect.new(rad_x - dx - 1,
  646.             (rad_y - dy - 1) % src.height,(dx << 1) + 1, 1))
  647.           blt(x - dx, y + dy, src, Rect.new(rad_x - dx - 1,
  648.             (rad_y + dy - 1) % src.height,(dx << 1) + 1, 1))
  649.         end
  650.       end
  651.       dx += 1
  652.     end while ry2 * (dx + 1) < rx2 * (dy - 0.5)
  653.     d = ry2 * (dx + 0.5) * (dx + 0.5) + rx2 * (dy - 1) * (dy - 1) - rx2 * ry2
  654.     sy = dy
  655.     begin
  656.       set_pixel(x + dx, y + dy, border_color)
  657.       set_pixel(x + dx, y - dy, border_color)
  658.       set_pixel(x - dx, y - dy, border_color)
  659.       set_pixel(x - dx, y + dy, border_color)
  660.       if fill_mode >= 0 and dy < sy
  661.         case fill_mode
  662.         when 0, 1
  663.           fill_rect(x - dx + 1, y - dy, (dx << 1) - 1, 1, f1)
  664.           fill_rect(x - dx + 1, y + dy, (dx << 1) - 1, 1, f2) unless dy == 0
  665.           if fill_mode == 1
  666.             f1.set(f1.red + dr, f1.green + dg, f1.blue + db, f1.alpha + da)
  667.             f2.set(f2.red - dr, f2.green - dg, f2.blue - db, f2.alpha - da)
  668.           end
  669.         when 2, 3
  670.           blt(x - dx + 1, y - dy, src, Rect.new(rad_x - dx,
  671.             (rad_y - dy - 1) % src.height,(dx << 1) - 1, 1))
  672.           blt(x - dx + 1, y + dy, src, Rect.new(rad_x - dx,
  673.             (rad_y + dy - 1) % src.height,(dx << 1) - 1, 1)) unless dy == 0
  674.         end
  675.       end
  676.       if d <= -1e-6
  677.         d += ry2 * (dx + 1 << 1) + rx2 * (3 - (dy << 1))
  678.         dx += 1
  679.       else
  680.         d += rx2 * (3 - (dy << 1))
  681.       end
  682.       dy -= 1
  683.     end while dy >= 0
  684.     src.dispose if fill_mode > 1
  685.   end
  686.   #--------------------------------------------------------------------------
  687.   # ● 传送位图圆
  688.   #     x : 圆心 X 坐标
  689.   #     y : 圆心 Y 坐标
  690.   #     rad : 半径
  691.   #     src_bitmap : 传送元位图
  692.   #     x0 : 传送圆心 X 坐标
  693.   #     y0 : 传送圆心 Y 坐标
  694.   #     opacity : 不透明度
  695.   #--------------------------------------------------------------------------
  696.   def blt_circle(x, y, rad, src_bitmap, x0, y0, opacity = 255)
  697.     blt_ellipse(x, y, rad, rad, src_bitmap, x0, y0, opacity)
  698.   end
  699.   #--------------------------------------------------------------------------
  700.   # ● 传送位图椭圆
  701.   #     x : 圆心 X 坐标
  702.   #     y : 圆心 Y 坐标
  703.   #     rad_x : 水平半径
  704.   #     rad_y : 垂直半径
  705.   #     src_bitmap : 传送元位图
  706.   #     x0 : 传送圆心 X 坐标
  707.   #     y0 : 传送圆心 Y 坐标
  708.   #     opacity : 不透明度
  709.   #--------------------------------------------------------------------------
  710.   def blt_ellipse(x, y, rad_x, rad_y, src_bitmap, x0, y0, opacity = 255)
  711.     raise ArgumentError if rad_x < 0 or rad_y < 0
  712.     return blt(x - rad_x, y, src_bitmap, Rect.new(x0 - rad_x, y0,
  713.       rad_x << 1, 1), opacity) if rad_y == 0
  714.     return blt(x, y - rad_y, src_bitmap, Rect.new(x0, y0 - rad_y,
  715.       1, rad_y << 1), opacity) if rad_x == 0
  716.     ry2 = rad_y * rad_y
  717.     rx2 = rad_x * rad_x
  718.     d = ry2 + rx2 * (0.25 - rad_y)
  719.     dx = 0
  720.     dy = rad_y
  721.     begin
  722.       if d <= -1e-6
  723.         d += ry2 * ((dx << 1) + 3)
  724.       else
  725.         blt(x - dx, y - dy, src_bitmap, Rect.new(x0 - dx, y0 - dy, dx << 1, 1),
  726.           opacity)
  727.         blt(x - dx, y + dy, src_bitmap, Rect.new(x0 - dx, y0 + dy, dx << 1, 1),
  728.           opacity)
  729.         d += ry2 * ((dx << 1) + 3) + rx2 * (1 - dy << 1)
  730.         dy -= 1
  731.       end
  732.       dx += 1
  733.     end while ry2 * (dx + 1) < rx2 * (dy - 0.5)
  734.     d = ry2 * (dx + 0.5) * (dx + 0.5) + rx2 * (dy - 1) * (dy - 1) - rx2 * ry2
  735.     begin
  736.       blt(x - dx, y - dy, src_bitmap, Rect.new(x0 - dx, y0 - dy, dx << 1, 1),
  737.         opacity)
  738.       blt(x - dx, y + dy, src_bitmap, Rect.new(x0 - dx, y0 + dy, dx << 1, 1),
  739.         opacity) unless dy == 0
  740.       if d <= -1e-6
  741.         d += ry2 * (dx + 1 << 1) + rx2 * (3 - (dy << 1))
  742.         dx += 1
  743.       else
  744.         d += rx2 * (3 - (dy << 1))
  745.       end
  746.       dy -= 1
  747.     end while dy >= 0
  748.   end
  749.   #--------------------------------------------------------------------------
  750.   # ● 绘制曲线
  751.   #     x1 : 起始点 X 坐标
  752.   #     x2 : 起始点 Y 坐标
  753.   #     cx1 : 控制点1 X 坐标
  754.   #     cy1 : 控制点1 Y 坐标
  755.   #     cx2 : 控制点2 X 坐标
  756.   #     cx2 : 控制点2 Y 坐标
  757.   #     x2 : 终止点(或控制点3) X 坐标
  758.   #     y2 : 终止点(或控制点3) Y 坐标
  759.   #     args : 后续的参数,可以追加额外的控制点,以最后一个点的坐标为终止点,
  760.   #            最后还需再指定一个颜色 (Color)
  761.   #--------------------------------------------------------------------------
  762.   def draw_curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, *args)
  763.     raise ArgumentError if args.size[0] == 0 or not args[-1].is_a?(Color)
  764.     color = args[-1]
  765.     points = [x1, y1, cx1, cy1, cx2, cy2, x2, y2].concat(args[0...-1])
  766.     draw_path(*get_curve_path(points).push(color))
  767.   end
  768.   #--------------------------------------------------------------------------
  769.   # ● 绘制封闭曲线
  770.   #     x1 : 起始点 X 坐标
  771.   #     x2 : 起始点 Y 坐标
  772.   #     cx1 : 控制点1 X 坐标
  773.   #     cy1 : 控制点1 Y 坐标
  774.   #     cx2 : 控制点2 X 坐标
  775.   #     cx2 : 控制点2 Y 坐标
  776.   #     x2 : 终止点 X 坐标
  777.   #     y2 : 终止点 Y 坐标
  778.   #     args : 后续的参数,每多指定一个曲线节点,增加6个参数,分别表示从前一终
  779.   #            止点作为起始点曲线的控制点1 X/Y、控制点2 X/Y、及本曲线终点的X/Y
  780.   #            最后还需再指定一个颜色 (Color)
  781.   #--------------------------------------------------------------------------
  782.   def draw_closed_curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, *args)
  783.     raise ArgumentError if args.size % 6 != 1 or not args[-1].is_a?(Color)
  784.     color = args[-1]
  785.     points = [x1, y1, cx1, cy1, cx2, cy2, x2, y2].concat(args[0...-1])
  786.     edges = []
  787.     0.step(points.size - 8, 6) do |i|
  788.       edges.concat(get_curve_path(points[i, 8]))
  789.     end
  790.     draw_polygon(*edges.push(color))
  791.   end
  792.   #--------------------------------------------------------------------------
  793.   # ● 绘制填充的封闭曲线
  794.   #     x1 : 起始点 X 坐标
  795.   #     x2 : 起始点 Y 坐标
  796.   #     cx1 : 控制点1 X 坐标
  797.   #     cy1 : 控制点1 Y 坐标
  798.   #     cx2 : 控制点2 X 坐标
  799.   #     cx2 : 控制点2 Y 坐标
  800.   #     x2 : 终止点 X 坐标
  801.   #     y2 : 终止点 Y 坐标
  802.   #     args : 后续的参数,每多指定一个曲线节点,增加6个参数,分别表示从前终止
  803.   #            点起始的下一曲线段控制点1 X/Y、控制点2 X/Y、及该曲线终止点的X/Y
  804.   #            最后要指定填充选项,填充选项有:
  805.   #            3个颜色 + true/false : 颜色1为边框色,颜色2和颜色3用于填充,最后
  806.   #              true = 垂直方向渐变 false = 水平方向渐变
  807.   #            3个颜色 : 颜色1用于描边,颜色2和颜色3用于填充,水平方向渐变
  808.   #            2个颜色 : 颜色1用于描边,颜色2用于填充
  809.   #            1个颜色 : 以该颜色描边,并实心填充
  810.   #            颜色 + 位图 + 数值 : 颜色用于描边,位图用于填充,数值为不透明度
  811.   #            颜色 + 位图 : 颜色用于描边,位图用于填充,不透明度固定为255
  812.   #--------------------------------------------------------------------------
  813.   def fill_closed_curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, *args)
  814.     case args[-1]
  815.     when FalseClass, TrueClass
  816.       arg_chop = -4
  817.     when Color
  818.       arg_chop = args[-3].is_a?(Color) ? -3 :
  819.         args[-2].is_a?(Color) ? -2 : -1
  820.     when Bitmap
  821.       arg_chop = -2
  822.     when Numeric
  823.       arg_chop = -3
  824.     else
  825.       raise ArgumentError
  826.     end
  827.     raise ArgumentError if (args.size + arg_chop) % 6 != 0
  828.     points = [x1, y1, cx1, cy1, cx2, cy2, x2, y2].concat(args[0...arg_chop])
  829.     edges = []
  830.     0.step(points.size - 8, 6) do |i|
  831.       edges.concat(get_curve_path(points[i, 8])[0...-2])
  832.     end
  833.     fill_polygon(*edges.concat(args[arg_chop..-1]))
  834.   end
  835.   #--------------------------------------------------------------------------
  836.   # ● 传送位图封闭曲线
  837.   #     x1 : 起始点 X 坐标
  838.   #     x2 : 起始点 Y 坐标
  839.   #     cx1 : 控制点1 X 坐标
  840.   #     cy1 : 控制点1 Y 坐标
  841.   #     cx2 : 控制点2 X 坐标
  842.   #     cx2 : 控制点2 Y 坐标
  843.   #     x2 : 终止点 X 坐标
  844.   #     y2 : 终止点 Y 坐标
  845.   #     args : 后续的参数,每多指定一个曲线节点,增加6个参数,分别表示从前终止
  846.   #            点起始的下一曲线段控制点1 X/Y、控制点2 X/Y、及该曲线终止点的X/Y
  847.   #            最后指定传送的位图, 偏移x,偏移y(比照起始点),(可选)不透明度
  848.   #--------------------------------------------------------------------------
  849.   def blt_closed_curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, *args)
  850.     if args[-3].is_a?(Bitmap)
  851.       start = -3
  852.       points = [x1, y1, cx1, cy1, cx2, cy2, x2, y2].concat(args[0...-3])
  853.     elsif args[-4].is_a?(Bitmap)
  854.       start = -4
  855.       points = [x1, y1, cx1, cy1, cx2, cy2, x2, y2].concat(args[0...-4])
  856.     else
  857.       raise ArgumentError
  858.     end
  859.     raise ArgumentError unless points.size % 6 == 2
  860.     edges = []
  861.     0.step(points.size - 8, 6) do |i|
  862.       edges.concat(get_curve_path(points[i, 8]))
  863.     end
  864.     blt_polygon(*edges.concat(args[start..-1]))
  865.   end
  866.   private
  867.   #--------------------------------------------------------------------------
  868.   # ● 内部函数:计算曲线点位
  869.   #     points : 接继点表
  870.   #--------------------------------------------------------------------------
  871.   def get_curve_path(points)
  872.     max_x = min_x = points[0]
  873.     max_y = min_y = points[1]
  874.     2.step(points.size - 2, 2) do |i|
  875.       max_x = [max_x, points[i]].max
  876.       min_x = [min_x, points[i]].min
  877.       max_y = [max_y, points[i + 1]].max
  878.       min_y = [min_y, points[i + 1]].min
  879.     end
  880.     curve_edge_count = [max_x + max_y - min_x - min_y >> 2, 2].max
  881.     (0..curve_edge_count).inject([]) do |a, i|
  882.       pt = points.clone
  883.       t = i / curve_edge_count.to_f
  884.       until pt.size == 2
  885.         pt = (0...(pt.size >> 1) - 1).to_a.inject([]) do |b, j|
  886.           x1, y1, x2, y2 = pt[j << 1, 4]
  887.           b.push((1 - t) * x1 + t * x2, (1 - t) * y1 + t * y2)
  888.         end
  889.       end
  890.       x = pt[0].round
  891.       y = pt[1].round
  892.       x == a[-2] && y == a[-1] ? a : a.push(x, y)
  893.     end
  894.   end
  895. end

评分

参与人数 5星屑 +360 +4 收起 理由
jienluck + 1
陈大帅帅帅哥 + 1 精品文章
fux2 + 360 精品文章
guoxiaomi + 1 精品文章
灯笼菜刀王 + 1 精品文章

查看全部评分

SailCat (小猫子·要开心一点) 共上站 24 次,发表过 11 篇文章 上 次 在: [2006年01月28日11:41:18 星期六] 从 [162.105.120.91] 到本站一游。

Lv5.捕梦者

梦石
0
星屑
39099
在线时间
5730 小时
注册时间
2006-11-10
帖子
6631
2
发表于 2022-11-21 10:02:25 | 只看该作者
正好是我需要的, 猫大威武

20种描绘图形很够用了, 不过还少了一种 "粘贴入" , 即 将 bitmapA 传送入 bitmapB 非空白像素里的绘制, 我曾经用 循环X和Y逐点blt的方式画入, 太没效率, 猫大能有更效率的方法么?

回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

遠航の猫咪

梦石
3
星屑
23209
在线时间
2387 小时
注册时间
2005-10-15
帖子
1166

开拓者

3
 楼主| 发表于 2022-11-21 10:21:23 | 只看该作者
灯笼菜刀王 发表于 2022-11-21 10:02
正好是我需要的, 猫大威武

20种描绘图形很够用了, 不过还少了一种 "粘贴入" , 即 将 bit ...

blt系的那些指令就是叠加粘贴啊,甚至你可以指定叠加不透明度的
bitmapB.blt_ellipse(x, y, rx, ry, bitmapA, x0, y0, opacity)
将bitmapA以x0,y0为圆心,rx, ry为长短轴的椭圆传送到bitmapB以x,y为圆心的位置
你看一下实现就知道,除了被blt的那些东西,并没有什么原来的像素被清除掉。

如果说真缺什么功能,那就是缺异型的stretch_blt,但这个我真的做不到,效率太低了。

点评

好的, 我试试看  发表于 2022-11-21 10:25
SailCat (小猫子·要开心一点) 共上站 24 次,发表过 11 篇文章 上 次 在: [2006年01月28日11:41:18 星期六] 从 [162.105.120.91] 到本站一游。
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
42640
在线时间
7613 小时
注册时间
2009-7-6
帖子
13506

开拓者贵宾

4
发表于 2022-11-21 11:50:39 | 只看该作者
很清晰地展示了各个方法的实现是最有参考价值的
不过效率方面一直是个麻烦的难题
RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
2
星屑
13473
在线时间
2312 小时
注册时间
2011-6-4
帖子
618
5
发表于 2022-11-21 17:30:59 | 只看该作者
强大如猫佬
回复 支持 反对

使用道具 举报

Lv5.捕梦者

梦石
0
星屑
36566
在线时间
10827 小时
注册时间
2009-3-15
帖子
4817
6
发表于 2022-11-21 18:07:02 | 只看该作者
有没拋物线的画法
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
3204
在线时间
319 小时
注册时间
2018-7-12
帖子
404
7
发表于 2022-11-21 19:35:10 | 只看该作者
环形计量槽是个非常有意思的设定,欲望之花开发初期也准备使用环形计量槽来着,但当时只使用切图和位移的手法来伪造环形,看样子现在有全新的处理方式了
回复 支持 0 反对 1

使用道具 举报

Lv2.观梦者

梦石
0
星屑
798
在线时间
113 小时
注册时间
2014-12-5
帖子
112
8
发表于 2023-1-26 03:36:35 | 只看该作者
有没有范例工程?

点评

没有  发表于 2023-1-26 11:29
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
3058
在线时间
157 小时
注册时间
2022-12-18
帖子
217
9
发表于 2023-1-26 15:59:56 | 只看该作者
很好很强大
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
7656
在线时间
1149 小时
注册时间
2006-7-18
帖子
597
10
发表于 2023-1-26 16:35:37 | 只看该作者
有没有教学,例子啊!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-12-18 10:02

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表