are you ready? Here we go... first, lets deal in center points: center of worker and center of building rectangle
what we want to do is find the intersection between the line that these two points make, and the lines which define the rectangle (actually, the lines that define the rectangle of the 'worker zone'
which gave me the formulas in simple enough terms...
here is some example code, highly commented and bloated - can be reduced down to just a few easy lines...
Code: Select all
' intersection of two lines
'
' line1 (100,100) - (300,200)
' line2 (100,200) - (300, 50)
'
'
dim shared as integer x, y
' Determine intersection of two lines:
sub LineIntersection(byval x1 as integer ,_
byval y1 as integer ,_
byval x2 as integer ,_
byval y2 as integer ,_
byval x3 as integer ,_
byval y3 as integer ,_
byval x4 as integer ,_
byval y4 as integer )
dim as single ua, ub
x = 0 : y = 0
ua = ( (x4-x3)*(y1-y3) - (y4-y3)*(x1-x3) ) / ( (y4-y3)*(x2-x1) - (x4-x3)*(y2-y1) )
ub = ( (x2-x1)*(y1-y3) - (y2-y1)*(x1-x3) ) / ( (y4-y3)*(x2-x1) - (x4-x3)*(y2-y1) )
if ua>0 and ua<1 and ub>0 and ub<1 then ' this checks to make sure the line segments intersects
y = y1 + ua * (y2 - y1)
x = x1 + ua * (x2 - x1)
end if
end sub
screenres 800,600,32
cls
locate 2,5: print "Just showing the intersection betweemn two lines - hit a key"
' draw the lines...
line (100,100)-(300,200), rgb(255,0,0)
line (100,200)-(300,50), rgb(255,0,0)
' find intersection...
x = 0 : y = 0
LineIntersection(100,100,300,200,100,200,300,50)
' show the intersection point
circle (x,y),10,rgb(0,255,0)
pset (x,y), rgb(255,255,255)
sleep
' so now that we can do that... lets do it with a rectangle!
type rect ' defined by upper left corner and lower right corner)
dim as integer x1
dim as integer y1
dim as integer x2
dim as integer y2
dim as integer cx
dim as integer cy
end type
dim worker as rect
dim building as rect
dim wdist as rect ' this is the rectangle that defines the working distance
dim as integer workdist, IntersectionX, IntersectionY
cls
' worker is a rect 32 x 32
worker.cx = 100 : worker.cy = 100
'don't care about worker rectangle....
worker.x1 = worker.cx - 16 : worker.y1 = worker.cy - 16
worker.x2 = worker.cx + 15 : worker.y2 = worker.cy + 15 ' 16 + 15 + 1(center) = 32 pixels
'draw worker...
line (worker.x1, worker.y1) - (worker.x2, worker.y2), rgb(0,0,255),bf ' blue box
' building is a rect 201 x 121 PLUS a certain distance from the building you want the worker to go to...
' so increase the rectangle by this distance (this is the distance from the building rectangle TO the worker CENTER!
workdist = 16 + 10 ' 16 is to adj from worker center, 10 is the actual distance
building.cx = 300 : building.cy = 200
building.x1 = building.cx - 100 : building.y1 = building.cy - 60
building.x2 = building.cx + 100 : building.y2 = building.cy + 60 ' 60 + 60 + 1(center) = 121 pixels(y)
'draw building...
line (building.x1, building.y1) - (building.x2, building.y2), rgb(255,0,0),bf ' red rectangle
'draw work distance from building....
wdist.x1 = building.x1 - workdist : wdist.y1 = building.y1 - workdist
wdist.x2 = building.x2 + workdist : wdist.y2 = building.y2 + workdist
line (wdist.x1, wdist.y1) - (wdist.x2, wdist.y2), rgb(128,0,0),b ' dim red rectangle, not filled
'draw line between worker and building....
line (worker.cx, worker.cy) - (building.cx, building.cy), rgb(0,64,0) ' dim green line
' now, here is the trick...:
' do a line intersection with all 4 sides of rectangle
'
LineIntersection(worker.cx, worker.cy, building.cx,building.cy,_ ' line from worker to building
wdist.x1, wdist.y1,_ ' top-left corner
wdist.x1, wdist.y2) ' bot-left corner
if x > 0 then IntersectionX = x
if y > 0 then IntersectionY = y
LineIntersection(worker.cx, worker.cy, building.cx,building.cy,_ ' line from worker to building
wdist.x1, wdist.y1,_ ' top-left corner
wdist.x2, wdist.y1) ' top-right corner
if x > 0 then IntersectionX = x
if y > 0 then IntersectionY = y
LineIntersection(worker.cx, worker.cy, building.cx,building.cy,_ ' line from worker to building
wdist.x1, wdist.y2,_ ' bot-left corner
wdist.x2, wdist.y2) ' bot-right corner
if x > 0 then IntersectionX = x
if y > 0 then IntersectionY = y
LineIntersection(worker.cx, worker.cy, building.cx,building.cy,_ ' line from worker to building
wdist.x2, wdist.y1,_ ' top-right corner
wdist.x2, wdist.y2) ' bot-right corner
if x > 0 then IntersectionX = x
if y > 0 then IntersectionY = y
' show the intersection point
locate 2,5 : print "The intersection point is at (";IntersectionX;",";IntersectionY;"), the worker should move to this point!
circle (Intersectionx,Intersectiony),10,rgb(0,255,0)
pset (Intersectionx,Intersectiony), rgb(255,255,255)
sleep
end