루비에서 하나의 변수에 여러 개의 사각형을 저장하고 싶습니다. 화면을 새로 고쳐야하는 직사각형을 추가하기 위해서입니다. 나는 위쪽, 왼쪽, 높이와 함께 클래스 Rectangle과 배열에 사각형 변수를 저장하려고 시도했다. 그러나 iterating하고 계산할 때 너무 느립니다.루비에 중복 영역이없는 많은 사각형을 효율적으로 저장하려고 시도합니다.
새 직사각형을 추가 할 때 새로 고칠 화면에 중복 된 것이 없어야하며 중복을 제거하기 위해 계산하는 데 시간이 많이 걸리지 않아야합니다 (최상의 경우 시간이 없음).
죄송합니다, 저는 영어 원어민이 아니며 많은 아이디어에 감사드립니다.
는 '사각형'
클래스 사각형
attr_accessor :top,:left,:height,:width
def initialize(options={})
@top=options[:top]
@left=options[:left]
@height=options[:height]
@width=options[:width]
end
def bottom
@[email protected]
end
def right
@[email protected]
end
def coveredBy?(rectangle)
return false if @top<rectangle.top
return false if @left<rectangle.left
return false if bottom>rectangle.bottom
return false if right>rectangle.right
return true
end
def intersection!(rectangle)
if @top<rectangle.top
@top=rectangle.top
end
if @left<rectangle.left
@left=rectangle.left
end
if bottom>(t=rectangle.bottom)
@[email protected]
end
if right>(t=rectangle.right)
@[email protected]
end
end
def &(rectangle)
if @top>=rectangle.top
[email protected]
else
top=rectangle.top
end
if @left>=rectangle.left
[email protected]
else
left=rectangle.left
end
if bottom<=rectangle.bottom
height=bottom+1-top
else
height=rectangle.bottom+1-top
end
return nil if height<=0
if right<=rectangle.right
width=right+1-left
else
width=rectangle.right+1-left
end
return nil if width<=0
return Rectangle.new(
:top=>top,
:left=>left,
:height=>height,
:width=>width
)
end
def -(rectArg)
return [] if empty?
return [self] if bottom<rectArg.top
return [self] if @top>rectArg.bottom
return [self] if right<rectArg.left
return [self] if @left>rectArg.right
ret=[]
[email protected]
if @top<rectArg.top
ret[ret.count]=Rectangle.new(
:top=>line,
:left=>@left,
:height=>[[email protected],@height].min,
:width=>@width
)
line=ret.first.bottom+1
end
if @left<rectArg.left
ret[ret.count]=Rectangle.new(
:top=>line,
:left=>@left,
:height=>[rectArg.bottom+1-line,bottom+1-line].min,
:width=>[[email protected],@width].min
)
end
if right>rectArg.right
ret[ret.count]=Rectangle.new(
:top=>line,
:left=>rectArg.right+1,
:height=>[rectArg.bottom+1-line,bottom+1-line].min,
:width=>[right-rectArg.right,@width].min
)
end
if bottom>rectArg.bottom
ret[ret.count]=Rectangle.new(
:top=>rectArg.bottom+1,
:left=>@left,
:height=>[bottom-rectArg.bottom,@height].min,
:width=>@width
)
end
ret
end
# Mit return true geht es deutlich schneller als mit ||.
def outside?(rectangle)
return true if empty?
return true if rectangle.empty?
return true if bottom<rectangle.top
return true if @top>rectangle.bottom
return true if right<rectangle.left
return true if @left>rectangle.right
return false
end
# nebeneinander oder Überschneidung
public def touching?(rectangle)
horizontalRange=((rectangle.left-1..(rectangle.left+rectangle.width)))
verticalRange=((rectangle.top-1..(rectangle.top+rectangle.height)))
horizontalRange.any?{|column|
[email protected]||[email protected][email protected]
} &&
verticalRange.any?{|line|
[email protected]||[email protected][email protected]
}
end
def ==(rectangle)
#rectangle.kind_of?(self.class) &&
@top==rectangle.top &&
@height==rectangle.height &&
@left==rectangle.left &&
@width==rectangle.width
end
def !=(rectangle)
!(self==rectangle)
end
def empty?
return true if top.nil?
return true if left.nil?
return true if height.nil?
return true if height<=0
return true if width.nil?
return true if width<=0
# @[email protected]<=0 || @width<=0 if @empty.nil?
# @empty
end
public def area
# @area||[email protected]*@width
# @area
@height*@width
end
# nur wenn sie passgenau nebeneinander liegen
# (Überschneidungen darf es nicht geben)
public def mergeHorizontally(rectangle)
return nil if @top!=rectangle.top
return nil if @height!=rectangle.height
if @[email protected]==rectangle.left
return Rectangle.new(
:top=>@top,
:left=>@left,
:height=>@height,
:width=>@width+rectangle.width
)
elsif [email protected]
return Rectangle.new(
:top=>rectangle.top,
:left=>rectangle.left,
:height=>rectangle.height,
:width=>[email protected]
)
else
return nil
end
end
# nur wenn sie passgenau nebeneinander liegen
# (Überschneidungen darf es nicht geben)
public def mergeVertically(rectangle)
return nil if @left!=rectangle.left
return nil if @width!=rectangle.width
if @[email protected]==rectangle.top
# return nil
return Rectangle.new(
:top=>@top,
:left=>@left,
:height=>@height+rectangle.height,
:width=>@width
)
elsif [email protected]
# return nil
return Rectangle.new(
:top=>rectangle.top,
:left=>rectangle.left,
:height=>[email protected],
:width=>rectangle.width
)
else
return nil
end
end
public def to_rects
Rectangles.new([self])
end
public def >(rectangle)
return true if @height>rectangle.height
return true if @width>rectangle.width
return false
end
public def +(rectArg)
# @@log<<"Rectangle#+ ==================================================="
# @@log<<"rectArg: #{rectArg.class}"
newTop=[@top,rectArg.top].min
newLeft=[@left,rectArg.left].min
newHeight=[bottom,rectArg.bottom].max+1-newTop
newWidth=[right,rectArg.right].max+1-newLeft
Rectangle.new(
:top=>newTop,
:left=>newLeft,
:height=>newHeight,
:width=>newWidth
)
end
끝을 필요로
당신은 객체가 동일한 지 여부를 확인하기 위해 자신의 방법을 정의 할 필요가
당신이 시도 코드를 게시하고 커뮤니티를 검토하시기 바랍니다. – Fencer04
그래서 ....... – user3756502