realbasic-nug
[Top] [All Lists]

2D Graphics: 2 or more objects moving relative to each other...

To: "REALbasic NUG" <realbasic-nug at lists dot realsoftware dot com>
Subject: 2D Graphics: 2 or more objects moving relative to each other...
From: "Philip Regan" <pregan at gmail dot com>
Date: Thu, 30 Mar 2006 21:46:22 -0500
Delivered-to: realbasic-nug at lists dot realsoftware dot com
Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition; b=T4dLrt5oUxrhLWSP81jkIIdmOkbF8pdZlojiGEUwfUZ90qu9NVvcl28RE9gUBPCMSpzMiqE0o0lJaVEcMUJIkdyTRh+9q9rYwmusl3pNq7kQOO8SOyACXsDNzlGxg7x/zICbpK4L5MIAsfECuQM9i42IOSV78NmS9XiEdReJ7ns=
I've been wracking my brain for two days now, and I just can't figure
this out. What's the 2D math to have two or more object relative to
each other? Below is what I have. It's close, but I can either make
all the object in the array "invert" their positions or orbit around
each other (looks cool, but not what I want).

Basically, I figured that the math would have been (old (X, Y) - new
(X, Y)) + Object(X, Y). But that doesn't seem to the case. Any
pointers would be keen because I'm tired of pounding my head on the
desk...

cheers
--
Philip Regan
pregan at gmail dot com
http://homepage.mac.com/pregan
REALBasic 2006r1, Applescript
Mac OS 10.3.9

Here's the code...
This code is the MouseDrag event of a custom canvas that's a tear down
and rebuild of Joe Strout's DragPic class to meet my needs. Objects
selected in the interface are placed into an array.
Canvas.MouseDrag(X as integer, Y as integer)
  //move the selected Object to the new position
  //MouseDown (x,y) is the pointer position when mouse button was pressed.
  //MouseDrag(x,y) is where the pointer was dragged to.

  dim i, n, q as integer
  dim OrigX, OrigY as integer
  dim OrigXz, OrigYz as integer
  dim OrigXi, OrigYi as integer
  dim NewX, NewY as integer
  dim NewXz, NewYz as integer
  dim NewXi, NewYi as integer
  dim changeX, changeY as integer
  dim boundTop, boundLeft, boundWidth, boundHeight as integer

  //if there's no object to work with or the mouse didn't drag, then
return to avoid NilObjectException
  if Ubound(ObjectSelectedArray) = -1 or Y = MouseDownY then return

  //Calculate ObjectSelectedArray(0) as base for Objects remaining
  for n = 0 to UBound(ObjectSelectedArray)
    if n = 0 then
      NewXz = SnapToX(X, ObjectSelectedArray(n))
      NewYz = SnapToY(Y, ObjectSelectedArray(n))

      OrigXz = ObjectSelectedArray(n).X
      OrigYz = ObjectSelectedArray(n).Y
      OrigXi = ObjectSelectedArray(n).Index
      OrigYi = ObjectSelectedArray(n).ScaleArrayIndex

      changeX = OrigXz - NewXz //THE FIRST PART GIVING ME THE HARD TIME
      changeY = OrigYz - NewYz

      //get the draw area bounds
      //X
      boundLeft = Min(OrigXz, NewXz)
      boundWidth = Max(OrigXz, NewXz) + ObjectSelectedArray(0).thePic.Width
      //Y
      boundTop = Min(OrigYz, NewYz)
      boundHeight = Max(OrigYz, NewYz) + ObjectSelectedArray(0).thePic.Height

      for i = 0 to Ubound(PosArrayX)
        if PosArrayX(i) = NewXz then
          NewXi = i
          Exit
        else
          NewXi = -1
        end if
      next

      for i = 0 to Ubound(PosArrayY)
        if PosArrayY(i) = NewYz then
          NewYi = i
          Exit
        else
          NewYi = -1
        end if
      next

      //apply the new (x,y) to the Object
      ObjectSelectedArray(n).X = NewXz
      ObjectSelectedArray(n).Y = NewYz
      ObjectSelectedArray(n).Index = NewXi
      ObjectSelectedArray(n).ScaleArrayIndex = NewYi

      //update the canvas
      RedrawBufferPic me.Graphics, boundLeft, boundTop, boundWidth, boundHeight

    else

      OrigX = ObjectSelectedArray(n).X
      OrigY = ObjectSelectedArray(n).Y
      OrigXi = ObjectSelectedArray(n).Index
      OrigYi = ObjectSelectedArray(n).ScaleArrayIndex

      NewX = changeX + OrigX //THE SECOND PART GIVING ME THE HARD TIME
      NewY = changeY + OrigY

      //get the draw area bounds
      //X
      boundLeft = Min(OrigX, NewX)
      boundWidth = Max(OrigX, NewX) + ObjectSelectedArray(n).thePic.Width
      //Y
      boundTop = Min(OrigY, NewY)
      boundHeight = Max(OrigY, NewY) + ObjectSelectedArray(n).thePic.Height

      for i = 0 to Ubound(PosArrayX)
        if PosArrayX(i) = NewX then
          NewXi = i
          Exit
        else
          NewXi = -1
        end if
      next

      for i = 0 to Ubound(PosArrayY)
        if PosArrayY(i) = NewY then
          NewYi = i
          Exit
        else
          NewYi = -1
        end if
      next

      //apply the new (x,y) to the Object
      ObjectSelectedArray(n).X = NewX
      ObjectSelectedArray(n).Y = NewY
      ObjectSelectedArray(n).Index = NewXi
      ObjectSelectedArray(n).ScaleArrayIndex = NewYi

      //update the canvas
      RedrawBufferPic me.Graphics, boundLeft, boundTop, boundWidth, boundHeight
    end if
  next
End Event

Function SnapToX(X as integer, theObject as ObjectObj) as integer
  //this returns the closest X-grid value for snapping
  //theObject as ObjectObj is legacy and no  longer needed

  dim NewX, SnapValue as integer
  dim GridIntervalX, GridToleranceX, offsetX, snapcX as integer

  GridIntervalX = 20
  //this is to future-proof for magnification of the editor view
  //X needs to be handled differently because Objects can have a
different length.
  //maybe do interval as global variables.

  GridToleranceX = GridIntervalX
  //BUG: Less than GridIntervalX causes the Object to flicker back and
forth to (X = 0)

  offsetX = 0 //assume closer to previous

  // is X closer to next grid line or prev one?
  //if x / Interval's remainder is greater than the interval, then go
to the next one
  if (X mod GridIntervalX) > (GridIntervalX) then
    offsetX = 1 ' closer to next
  end if

  // Get snap coordinate rounded to nearest grid interval
  //X / interval + 1 * interval
  snapcX = (X \ GridIntervalX + offsetX) * GridIntervalX

  if abs(X - snapcX) < GridToleranceX then
    NewX = snapcX
    if NewX > bufferPic.Width - GridIntervalX then NewX =
bufferPic.Width - GridIntervalX
  end if

  return NewX
end function

Function SnapToY(Y as integer, theObject as ObjectObj) as integer
  //this returns the closest Y-grid value for snapping
  //theObject as ObjectObj is legacy and no  longer needed
  dim NewY, SnapValue as integer
  dim GridIntervalY, GridToleranceY, offsetY, snapcY as integer

  GridIntervalY = 20
  //this is to future-proof for magnification of the editor view
  //Y needs to be handled differently because Objects can have a
different length.
  //maybe do interval as global variables.

  GridToleranceY = GridIntervalY
  //BUG: Less than GridIntervalY causes the Object to flicker back and
forth to (Y = 0)

  offsetY = 0 //assume closer to previous

  // is Y closer to neYt grid line or prev one?
  //if Y / Interval's remainder is greater than the interval, then go
to the neYt one
  if (Y mod GridIntervalY) > (GridIntervalY) then
    offsetY = 1 ' closer to neYt
  end if

  // Get snap coordinate rounded to nearest grid interval
  //Y / interval + 1 * interval
  snapcY = (Y \ GridIntervalY + offsetY) * GridIntervalY

  if abs(Y - snapcY) < GridToleranceY then
    NewY = snapcY
    if NewY > bufferPic.Width - GridIntervalY then NewY =
bufferPic.Width - GridIntervalY
  end if

  return NewY
end function
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>


<Prev in Thread] Current Thread [Next in Thread>