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>
|