- live browsing of Self object memory -

lobby traitsrectangle

A rectangle is defined by two points making up opposing corners.
      Make that a PAIR of points--incredibly useful-dmu

CopyDowns: vector

CreatorPath: traits rectangle

Module: rectangle

parent* = traits pair

accessing

bottom = ( corner y)
bottom: = ( copy corner: right @ n)
bottomCenter = ( (left mean: right) @ bottom)
bottomLeft = ( left @ bottom)
bottomLeft: = ( copy from: topRight To: pt)
bottomRight = ( corner)
bottomRight: = ( copy corner: pt)
center = ( (left mean: right) @ (top mean: bottom))
center: = ( center: pt Size: size)
left = ( origin x)
left: = ( copy origin: n @ top)
leftCenter = ( left @ (top mean: bottom))
right = ( corner x)
right: = ( copy corner: n @ bottom)
rightCenter = ( right @ (top mean: bottom))
top = ( origin y)
top: = ( copy origin: left @ n)
topCenter = ( (left mean: right) @ top)
topLeft = ( origin)
topLeft: = ( copy origin: pt)
topRight = ( right @ top)
topRight: = ( copy from: bottomLeft To: pt)

comparing

= = ( r equalsRectangle: self)
equalsRectangle: = ( (origin = r origin) && [corner = r corner])

composing

extend: = ( indent: n negate)
indent: =
( 
      ((origin x + n) @ (origin y + n))
    # ((corner x - n) @ (corner y - n)))
intersect: =
( | b. l. r. t |
    l:   left max: rect left.
    r:  right min: rect right.
    t:    top max: rect top.
    b: bottom min: rect bottom.
    (l >= r) || [t >= b] ifTrue: [ ^ (0@0) # (-1 @ -1) ].
    (l @ t) # (r @ b))
union: = ( (origin min: rect origin) # (corner max: rect corner))

creating

center:Size: =
( | or |
    or: c - (s / 2).
    from: or To: or + s)
from:To: =
( | r |
    r: copy.
    r origin:  pt1 min: pt2.
    r corner:  pt1 max: pt2.
    r)

filing out

isImmutableForFilingOut = true
storeStringWorks = true

pairNess

copyX:Y: = ( (copy origin: newX) corner: newY)
x = ( origin)
y = ( corner)

printing

separator = ' # '

sizing

area = ( width * height)
height = ( bottom - top)
size = ( width @ height)
width = ( right - left)

stretching

shrinkBottom: = ( origin # (corner subtractY: n))
shrinkBottomRight: = ( origin # (corner - p))
shrinkLeft: = ( (origin addX: n) # corner)
shrinkRight: = ( origin # (corner subtractX: n))
shrinkTop: = ( (origin addY: n) # corner)
shrinkTopLeft: = ( (origin + p) # corner)
stretchBottom: = ( origin # (corner addY: n))
stretchBottomRight: = ( origin # (corner + p))
stretchLeft: = ( (origin subtractX: n) # corner)
stretchRight: = ( origin # (corner addX: n))
stretchTop: = ( (origin subtractY: n) # corner)
stretchTopLeft: = ( (origin - p) # corner)

testing

encloses: =
( 
    (left   < rect left ) && [
    (right  > rect right) && [
    (top    < rect top  ) && [
     bottom > rect bottom ]]])
enclosesOrEquals: =
( 
    (left   <= rect left ) && [
    (right  >= rect right) && [
    (top    <= rect top  ) && [
     bottom >= rect bottom ]]])
includes: =
( 
        (pt x  >=  left )
    && [(pt x  <=  right)
    && [(pt y  >=  top  )
    && [ pt y  <=  bottom ]]])
intersects: =
( 
    ((left max: rect left) <= (right  min: rect right )) &&
    [(top  max: rect top ) <= (bottom min: rect bottom)])

translating

translateBy: = ( copy from: origin + offset To: corner + offset)
translateTo: = ( copy from: pt To: pt + size)move origin of rectangle to pt

ui

deltaList: =
( | c |
    c: list copyRemoveAll.
    (intersects: rect) ifFalse: [ ^ c add: self ].
    top < rect top ifTrue: [
        c add: topLeft # (right @ rect top predecessor) ].
    left < rect left ifTrue: [ 
        c add: bottomLeft
             # (rect left predecessor @ (top max: rect top)) ].
    right > rect right ifTrue: [ 
        c add: (rect right successor @ (top max: rect top))
              # bottomRight ].
    bottom > rect bottom ifTrue: [ 
        c add: ((left max: rect left) @ rect bottom successor)
                # ((right min: rect right) @ bottom) ].
    c)
return a list of rectangles composing the region the returned rectangles do not overlap rect. These methods may go better somewhere else, but I don't know where yet--dmu 2/91
pointClosestToPoint: =
( | x. y |
    x: left    >  p x ifTrue: [ left   ] False: [
       right   <= p x ifTrue: [ right  ] False: [ p x ]].
    y: top     >  p y ifTrue: [ top    ] False: [
       bottom  <= p y ifTrue: [ bottom ] False: [ p y ]].
    x @ y)
pointClosestToRectangle: =
( | x. y |
    x: left    >  r right ifTrue: [ left   ] False: [
       right   <= r left  ifTrue: [ right  ] False: [ 
           (left max: r left) mean: (right min: r right) ]].
    y: top     >  r bottom ifTrue: [ top    ] False: [
       bottom  <= r top    ifTrue: [ bottom ] False: [ 
           (top max: r top) mean: (bottom min: r bottom) ]].
    x @ y)
restrictTo: =
( | x. y |
    x: case
      if: [ width >= enclosingRect width ]  Then: [ enclosingRect center x - width half ]
      If: [ left  <  enclosingRect left  ]  Then: [ enclosingRect left ]
      If: [ right >  enclosingRect right ]  Then: [ enclosingRect right - width ]
      Else: [ left ].

    y: case
      if: [ height >= enclosingRect height ]  Then: [ enclosingRect center y - height half ]
      If: [ top    <  enclosingRect top    ]  Then: [ enclosingRect top ]
      If: [ bottom >  enclosingRect bottom ]  Then: [ enclosingRect bottom - height ]
      Else: [ top ].

    translateTo: x @ y)
Translate me if need be so I will not stick out from enclosingRect. If hopeless, center me. -- Ungar, 6/19/95
skippedAreaTo: =
( 
     "must not include x (new box)"
    (  isWestOf:  x   )  ifTrue: [ skippedAreaEastwardsTo:  x ] False: [
    (x isWestOf:  self)  ifTrue: [ skippedAreaWestwardsTo:  x ] False: [
    (  isNorthOf: x   )  ifTrue: [ skippedAreaSouthwardsTo: x ] False: [
    (x isNorthOf: self)  ifTrue: [ skippedAreaNorthwardsTo: x ] False: [
        vector]]]])
isNorthOf: = ( (x top - top ) > 1)
isWestOf: = ( (x left - left) > 1)
skippedAreaEastwardsTo: =
( | pts |
     "
         self is west of x, so go east to fill
     "
    (  isNorthOf: x   ) ifTrue: [skippedAreaSEwardsTo: x] False: [
    (x isNorthOf: self) ifTrue: [skippedAreaNEwardsTo: x] False: [
       pts: vector copySize: 4.
       pts at: 0 Put:   topLeft.
       pts at: 1 Put:   bottomLeft.
       pts at: 2 Put: x bottomLeft.
       pts at: 3 Put: x topLeft.
       pts
    ]])
skippedAreaNEwardsTo: =
( | pts |
    pts: vector copySize: 6.
    pts at: 0 Put:   topLeft.
    pts at: 1 Put:   bottomLeft.
    pts at: 2 Put:   bottomRight.
    pts at: 3 Put: x bottomRight + (0 @ 1).
    pts at: 4 Put: x bottomLeft  + (0 @ 1).
    pts at: 5 Put: x topLeft     + (0 @ 0).
    pts)
return a polygon in between two rectangles for inserting motion blur. There are lots of +1 hacks to get around GX polygons
skippedAreaNWwardsTo: =
( | pts |
    pts: vector copySize: 6.
    pts at: 0 Put:   topRight.
    pts at: 1 Put:   bottomRight.
    pts at: 2 Put:   bottomLeft.
    pts at: 3 Put: x bottomLeft  + (0 @ 1).
    pts at: 4 Put: x bottomRight + (1 @ 1).
    pts at: 5 Put: x topRight    + (1 @ 0).
    pts)
skippedAreaNorthwardsTo: =
( | pts |
    pts: vector copySize: 4.
    pts at: 0 Put:   bottomLeft.
    pts at: 1 Put:   bottomRight.
    pts at: 2 Put: x bottomRight + (0 @ 1).
    pts at: 3 Put: x bottomLeft  + (0 @ 1).
    pts)
skippedAreaSEwardsTo: =
( | pts |
    pts: vector copySize: 6.
    pts at: 0 Put:   bottomLeft.
    pts at: 1 Put:   topLeft.
    pts at: 2 Put:   topRight.
    pts at: 3 Put: x topRight.
    pts at: 4 Put: x topLeft.
    pts at: 5 Put: x bottomLeft.
    pts)
skippedAreaSWwardsTo: =
( | pts |
    pts: vector copySize: 6.
    pts at: 0 Put:   bottomRight.
    pts at: 1 Put:   topRight.
    pts at: 2 Put:   topLeft.
    pts at: 3 Put: x topLeft     + (1 @ 0).
    pts at: 4 Put: x topRight    + (1 @ 0).
    pts at: 5 Put: x bottomRight + (1 @ 0).
    pts)
skippedAreaSouthwardsTo: =
( | pts |
    pts: vector copySize: 4.
    pts at: 0 Put:   topLeft.
    pts at: 1 Put:   topRight.
    pts at: 2 Put: x topRight.
    pts at: 3 Put: x topLeft.
    pts)
skippedAreaWestwardsTo: =
( | pts |
     "
         self is west of x, so go east to fill
     "
    (  isNorthOf: x   ) ifTrue: [skippedAreaSWwardsTo: x] False: [
    (x isNorthOf: self) ifTrue: [skippedAreaNWwardsTo: x] False: [
       pts: vector copySize: 4.
       pts at: 0 Put:   topRight.
       pts at: 1 Put:   bottomRight.
       pts at: 2 Put: x bottomRight + (1 @ 0).
       pts at: 3 Put: x topRight    + (1 @ 0).
       pts
    ]])