如何在Ruby2D中为可编辑图形实现正确的边框效果?
Ruby2D图形编辑器边框偏移问题解决
我用Ruby2D开发简易2D图形编辑器,做图形边框时采用「同类型图形放大后置于主图形后方」的方案,但调整主图形形状时,边框无法维持初始偏移量,仅跟随主图形顶点同步变化,最终呈现类似阴影的效果。
效果对比
- 默认状态:

- 调整后状态:

问题根源
原代码的change方法中,直接将边框顶点与主图形顶点设为相同值,丢失了初始化时定义的固定偏移量。初始化时边框每个顶点相对于主图形顶点有明确偏移(如x1不变、y1减2;x2加2、y2加2等),但调整操作未重新应用该偏移。
修复方案
步骤1:保存初始偏移量
在initialize方法中记录边框顶点相对于主图形顶点的偏移值,确保调整时可复用该偏移规则。
步骤2:更新边框时重新应用偏移
修改change方法,每次主图形顶点更新后,以新顶点为基础加上初始偏移量,计算边框的新位置。
修改后的完整代码
def check_point(event) $array_of_figures.each do |element| element.hash_of_cp.each{|name,cp| @element=element,cp if cp.contains?event.x,event.y} end end update do on :mouse_down do |event| check_point(event) on :mouse_move do |smth| @element[0].change(smth,@element[1]) if @element!=0 end on :mouse_up do|this| if @element!=0 @element[0].change(this,@element[1]) @element=0 end end end end show class N3 < Figure def initialize super @premitive=Triangle.new( x1: 60, y1: 10, x2: 110, y2: 100, x3: 10, y3: 100, color: 'yellow', z: 100 ) # 保存边框相对于主图形的顶点偏移量 @border_offsets = { x1: 0, y1: -2, x2: 2, y2: 2, x3: -2, y3: 2 } @arc=Triangle.new( x1: @premitive.x1 + @border_offsets[:x1], y1: @premitive.y1 + @border_offsets[:y1], x2: @premitive.x2 + @border_offsets[:x2], y2: @premitive.y2 + @border_offsets[:y2], x3: @premitive.x3 + @border_offsets[:x3], y3: @premitive.y3 + @border_offsets[:y3], color: 'white', z: 99 ) @hash_of_cp[:x1_cp]=Circle.new( x: @premitive.x1, y: @premitive.y1, radius: 3, sectors: 32, color: 'lime', z: 101 ) @hash_of_cp[:x2_cp]=Circle.new( x: @premitive.x2, y: @premitive.y2, radius: 3, sectors: 32, color: 'lime', z: 101 ) @hash_of_cp[:x3_cp]=Circle.new( x: @premitive.x3, y: @premitive.y3, radius: 3, sectors: 32, color: 'lime', z: 101 ) @center=Circle.new( x: (@premitive.x1+@premitive.x2+@premitive.x3)/3 , y: (@premitive.y1+@premitive.y2+@premitive.y3)/3, radius: 3, sectors: 32, color: 'lime', z: 101 ) end def change(smth,cp) if @premitive.x1==cp.x && @premitive.y1==cp.y @premitive.x1=smth.x @premitive.y1=smth.y elsif @premitive.x2==cp.x && @premitive.y2==cp.y @premitive.x2=smth.x @premitive.y2=smth.y elsif @premitive.x3==cp.x && @premitive.y3==cp.y @premitive.x3=smth.x @premitive.y3=smth.y end # 更新边框顶点,重新应用偏移量 @arc.x1 = @premitive.x1 + @border_offsets[:x1] @arc.y1 = @premitive.y1 + @border_offsets[:y1] @arc.x2 = @premitive.x2 + @border_offsets[:x2] @arc.y2 = @premitive.y2 + @border_offsets[:y2] @arc.x3 = @premitive.x3 + @border_offsets[:x3] @arc.y3 = @premitive.y3 + @border_offsets[:y3] @center.x=(@premitive.x1+@premitive.x2+@premitive.x3)/3 @center.y=(@premitive.y1+@premitive.y2+@premitive.y3)/3 cp.x =smth.x cp.y =smth.y end end
额外优化建议
- 将偏移量设为可配置参数,方便后续调整边框宽度;
- 对于矩形、多边形等其他图形,可复用相同思路:保存顶点偏移规则,主图形更新后重新计算边框位置。
内容的提问来源于stack exchange,提问作者Artem Artemov
相关产品推荐
相关产品推荐

