## Getting distance

### Getting distance

I want to make my games background become a darker shade of red the closer one rectangle is to another, and become more white the farther they are, but I dont know how to use love.physics.getDistance(), and dont know how to properly set the background the way i want it. Can anyone lend a hand?

- zorg
- Party member
**Posts:**2805**Joined:**Thu Dec 13, 2012 2:55 pm**Location:**Absurdistan, Hungary-
**Contact:**

### Re: Getting distance

The easiest solution would be to not use love.physics, and do this:But you can probably adapt this to your needs

Code: Select all

```
local rect1 = {0,0,50,50}
local rect2 = {500,500,50,50}
local mindistance = 100
local maxdistance = 400
local mincolor = {255,255,255}
local maxcolor = {0,0,64}
local color = {0,0,0}
-- in love.update:
-- rectangle center points
local c1, c2
-- distance between center points
local distance = math.sqrt(c1^2.0 + c2^2.0)
-- normalize distance based on min and max distances
local ratio = (math.min(maxdistance, math.max(mindistance,distance)) - mindistance) / (maxdistance - mindistance)
-- adjust color
color[1] = mincolor[1] * ratio + maxcolor[1] * (1.0-ratio)
color[2] = mincolor[2] * ratio + maxcolor[2] * (1.0-ratio)
color[3] = mincolor[3] * ratio + maxcolor[3] * (1.0-ratio)
-- in love.draw:
love.graphics.setBackgroundColor(color)
-- then set the color to something else, and draw two rectangles.
```

Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

- substitute541
- Party member
**Posts:**484**Joined:**Fri Aug 24, 2012 9:04 am**Location:**Southern Leyte, Visayas, Philippines-
**Contact:**

### Re: Getting distance

Using more sensible function names. Untested, but I think maybe it works. Been a long time since I coded in Lua.

Code: Select all

```
-- Here be your rectangles
-- They be located at the pixel coordinates (x, y)
-- Their dimensions are specified as well
local foo = {
x = 0,
y = 0,
width = 500,
height = 200
}
local bar = {
x = 100,
y = 10,
width = 600,
height = 100
}
-- Let's make a function that gets the center of a rectangle.
-- Returns two values: x and y
function getRectangleCenter( r )
return r.x + r.width / 2, r.y + r.height / 2
end
-- Now this one gets the distance using good ol' Pythagorean Theorem
function getDistance( ax, ay, bx, by )
local dx = bx - ax
local dy = by - ay
return math.sqrt( dx*dx + dy*dy )
end
-- This clamp a number's range. This keeps x no greater than rightEdge, and no
-- lesser than leftEdge
function clamp( leftEdge, rightEdge, x )
return math.min( rightEdge, math.max( leftEdge, x ) )
end
-- This transforms a value between leftEdge and rightEdge to 0.0 and 1.0.
-- Convenient for advanced number stuffs
function normalize( leftEdge, rightEdge, x )
return ( x - leftEdge ) / ( rightEdge - leftEdge )
end
-- And this transforms a value between 0.0 and 1.0 to leftEdge and rightEdge
-- I actually don't know the precise name, so I'm using "scale"
function scale( leftEdge, rightEdge, x )
return x * ( rightEdge - leftEdge ) + leftEdge
end
-- And now, somewhere in your love.update:
-- ===
-- note: if you ARE using love physics, you can find the rect center in a
-- different way
local ax, ay = getRectangleCenter( foo )
local bx, by = getRectangleCenter( bar )
local distance = getDistance( ax, ay, bx, by )
local ratio = normalize( minDistance, maxDistance, clamp( minDistance, maxDistance, distance ) )
-- alternatively:
-- local ratio = clamp( 0, 1, normalize( minDistance, maxDistance, distance ) )
color[1] = scale( mincolor[1], maxcolor[1], ratio )
color[2] = scale( mincolor[2], maxcolor[2], ratio )
color[3] = scale( mincolor[3], maxcolor[3], ratio )
-- in love.draw:
love.graphics.setBackgroundColor(color)
-- then set the color to something else, and draw two rectangles.
```

Currently designing themes for WordPress.

Sometimes lurks around the forum.

Sometimes lurks around the forum.

### Re: Getting distance

zorg wrote:The easiest solution would be to not use love.physics, and do this:But you can probably adapt this to your needsCode: Select all

`local rect1 = {0,0,50,50} local rect2 = {500,500,50,50} local mindistance = 100 local maxdistance = 400 local mincolor = {255,255,255} local maxcolor = {0,0,64} local color = {0,0,0} -- in love.update: -- rectangle center points local c1, c2 -- distance between center points local distance = math.sqrt(c1^2.0 + c2^2.0) -- normalize distance based on min and max distances local ratio = (math.min(maxdistance, math.max(mindistance,distance)) - mindistance) / (maxdistance - mindistance) -- adjust color color[1] = mincolor[1] * ratio + maxcolor[1] * (1.0-ratio) color[2] = mincolor[2] * ratio + maxcolor[2] * (1.0-ratio) color[3] = mincolor[3] * ratio + maxcolor[3] * (1.0-ratio) -- in love.draw: love.graphics.setBackgroundColor(color) -- then set the color to something else, and draw two rectangles.`

this code confuses me, probably cuz im still new to lua..

first off, if I set rect1 and rect2's x and why values in load, how am I supposed to draw the rectangle and change the values.

also, you create variables c1 and c2 then do

Code: Select all

`local distance = math.sqrt(c1^2.0 + c2^2.0)`

### Re: Getting distance

he didn't tell you to set them in love.load. If you do, then you need to make them global, otherwise you can leave them like this and keep it before love.update and draw.Vimm wrote: first off, if I set rect1 and rect2's x and why values in load, how am I supposed to draw the rectangle and change the values.

he left out that part, you would need to set them, and they should probably be called something like dx, dy (because they're supposed to be the differences on the two axes) - I think zorg got a little confused there because the comment doesn't really fit.Vimm wrote: also, you create variables c1 and c2 then do, but c1 and c2 are never given a value or anything, from what i can tell, so it looks like you're getting the square root of nil. Am I just missing something?Code: Select all

`local distance = math.sqrt(c1^2.0 + c2^2.0)`

Anyway, you probably won't want to copy that code. It makes more sense to understand what it does and how (the math) and apply it to what you have already.

Basically there are three interesting points in there:

1.) getting the distance between two points

- use pythagoras. The distance between two points is math.sqrt(dx * dx + dy * dy) where dx and dy are the differences between two x and y coordinates respectively. It does not matter where you get the points from, in zorg's example you would use the centers of the rectangles and calculate them like this: dx = (rect1[1] + rect1[3]/2) - (rect2[1] + rect2[3]/2) (distance between the centers). If you use love.physics, you can use x1, y2 = body1:getWorldCenter() etc. and calculate them like dx = x1 - x2.

2.) mapping the distance range to a value between 0 and 1 for easy processing

("normalizing" it). Basically, if the distance is the minimum distance or less, make the value be 0, if it is the maximum or more make it be 1, and if it is inbetween make it be inbetween 0 and 1. That's the

Code: Select all

```
-- normalize distance based on min and max distances
local ratio = (math.min(maxdistance, math.max(mindistance,distance)) - mindistance) / (maxdistance - mindistance)
```

3.) using that 0-1 value to fade between two colors:

Code: Select all

```
-- adjust color
color[1] = mincolor[1] * ratio + maxcolor[1] * (1.0-ratio)
color[2] = mincolor[2] * ratio + maxcolor[2] * (1.0-ratio)
color[3] = mincolor[3] * ratio + maxcolor[3] * (1.0-ratio)
```

### Re: Getting distance

oh okay, i see what ur getting at, I think its going to take me quite a while to fully understand it and be able to implement it though. Don't know if it's hard to do or if I'm just bads-ol wrote:he didn't tell you to set them in love.load. If you do, then you need to make them global, otherwise you can leave them like this and keep it before love.update and draw.Vimm wrote: first off, if I set rect1 and rect2's x and why values in load, how am I supposed to draw the rectangle and change the values.

he left out that part, you would need to set them, and they should probably be called something like dx, dy (because they're supposed to be the differences on the two axes) - I think zorg got a little confused there because the comment doesn't really fit.Vimm wrote: also, you create variables c1 and c2 then do, but c1 and c2 are never given a value or anything, from what i can tell, so it looks like you're getting the square root of nil. Am I just missing something?Code: Select all

`local distance = math.sqrt(c1^2.0 + c2^2.0)`

Anyway, you probably won't want to copy that code. It makes more sense to understand what it does and how (the math) and apply it to what you have already.

Basically there are three interesting points in there:

1.) getting the distance between two points

- use pythagoras. The distance between two points is math.sqrt(dx * dx + dy * dy) where dx and dy are the differences between two x and y coordinates respectively. It does not matter where you get the points from, in zorg's example you would use the centers of the rectangles and calculate them like this: dx = (rect1[1] + rect1[3]/2) - (rect2[1] + rect2[3]/2) (distance between the centers). If you use love.physics, you can use x1, y2 = body1:getWorldCenter() etc. and calculate them like dx = x1 - x2.

2.) mapping the distance range to a value between 0 and 1 for easy processing

("normalizing" it). Basically, if the distance is the minimum distance or less, make the value be 0, if it is the maximum or more make it be 1, and if it is inbetween make it be inbetween 0 and 1. That's thepart of zorg's code.Code: Select all

`-- normalize distance based on min and max distances local ratio = (math.min(maxdistance, math.max(mindistance,distance)) - mindistance) / (maxdistance - mindistance)`

3.) using that 0-1 value to fade between two colors:Code: Select all

`-- adjust color color[1] = mincolor[1] * ratio + maxcolor[1] * (1.0-ratio) color[2] = mincolor[2] * ratio + maxcolor[2] * (1.0-ratio) color[3] = mincolor[3] * ratio + maxcolor[3] * (1.0-ratio)`

- zorg
- Party member
**Posts:**2805**Joined:**Thu Dec 13, 2012 2:55 pm**Location:**Absurdistan, Hungary-
**Contact:**

### Re: Getting distance

Yep, sorry, was a bit tired when i wrote that, though as s-ol said:

s-ol wrote:Anyway, you probably won't want to copy that code. It makes more sense to understand what it does and how (the math) and apply it to what you have already.

Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

- substitute541
- Party member
**Posts:**484**Joined:**Fri Aug 24, 2012 9:04 am**Location:**Southern Leyte, Visayas, Philippines-
**Contact:**

### Re: Getting distance

Not to be an annoying d--- but did anyone actually read what I posted?

I used @zorg's code and refactored it to use functions.

I used @zorg's code and refactored it to use functions.

substitute541 wrote:Using more sensible function names. Untested, but I think maybe it works. Been a long time since I coded in Lua.

Code: Select all

`-- Here be your rectangles -- They be located at the pixel coordinates (x, y) -- Their dimensions are specified as well local foo = { x = 0, y = 0, width = 500, height = 200 } local bar = { x = 100, y = 10, width = 600, height = 100 } -- Let's make a function that gets the center of a rectangle. -- Returns two values: x and y function getRectangleCenter( r ) return r.x + r.width / 2, r.y + r.height / 2 end -- Now this one gets the distance using good ol' Pythagorean Theorem function getDistance( ax, ay, bx, by ) local dx = bx - ax local dy = by - ay return math.sqrt( dx*dx + dy*dy ) end -- This clamp a number's range. This keeps x no greater than rightEdge, and no -- lesser than leftEdge function clamp( leftEdge, rightEdge, x ) return math.min( rightEdge, math.max( leftEdge, x ) ) end -- This transforms a value between leftEdge and rightEdge to 0.0 and 1.0. -- Convenient for advanced number stuffs function normalize( leftEdge, rightEdge, x ) return ( x - leftEdge ) / ( rightEdge - leftEdge ) end -- And this transforms a value between 0.0 and 1.0 to leftEdge and rightEdge -- I actually don't know the precise name, so I'm using "scale" function scale( leftEdge, rightEdge, x ) return x * ( rightEdge - leftEdge ) + leftEdge end -- And now, somewhere in your love.update: -- === -- note: if you ARE using love physics, you can find the rect center in a -- different way local ax, ay = getRectangleCenter( foo ) local bx, by = getRectangleCenter( bar ) local distance = getDistance( ax, ay, bx, by ) local ratio = normalize( minDistance, maxDistance, clamp( minDistance, maxDistance, distance ) ) -- alternatively: -- local ratio = clamp( 0, 1, normalize( minDistance, maxDistance, distance ) ) color[1] = scale( mincolor[1], maxcolor[1], ratio ) color[2] = scale( mincolor[2], maxcolor[2], ratio ) color[3] = scale( mincolor[3], maxcolor[3], ratio ) -- in love.draw: love.graphics.setBackgroundColor(color) -- then set the color to something else, and draw two rectangles.`

Currently designing themes for WordPress.

Sometimes lurks around the forum.

Sometimes lurks around the forum.

- zorg
- Party member
**Posts:**2805**Joined:**Thu Dec 13, 2012 2:55 pm**Location:**Absurdistan, Hungary-
**Contact:**

### Re: Getting distance

(I did, honestly)

Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

### Re: Getting distance

s-ol wrote:he didn't tell you to set them in love.load. If you do, then you need to make them global, otherwise you can leave them like this and keep it before love.update and draw.Vimm wrote: first off, if I set rect1 and rect2's x and why values in load, how am I supposed to draw the rectangle and change the values.

he left out that part, you would need to set them, and they should probably be called something like dx, dy (because they're supposed to be the differences on the two axes) - I think zorg got a little confused there because the comment doesn't really fit.Vimm wrote: also, you create variables c1 and c2 then do, but c1 and c2 are never given a value or anything, from what i can tell, so it looks like you're getting the square root of nil. Am I just missing something?Code: Select all

`local distance = math.sqrt(c1^2.0 + c2^2.0)`

Anyway, you probably won't want to copy that code. It makes more sense to understand what it does and how (the math) and apply it to what you have already.

Basically there are three interesting points in there:

1.) getting the distance between two points

- use pythagoras. The distance between two points is math.sqrt(dx * dx + dy * dy) where dx and dy are the differences between two x and y coordinates respectively. It does not matter where you get the points from, in zorg's example you would use the centers of the rectangles and calculate them like this: dx = (rect1[1] + rect1[3]/2) - (rect2[1] + rect2[3]/2) (distance between the centers). If you use love.physics, you can use x1, y2 = body1:getWorldCenter() etc. and calculate them like dx = x1 - x2.

2.) mapping the distance range to a value between 0 and 1 for easy processing

("normalizing" it). Basically, if the distance is the minimum distance or less, make the value be 0, if it is the maximum or more make it be 1, and if it is inbetween make it be inbetween 0 and 1. That's thepart of zorg's code.Code: Select all

`-- normalize distance based on min and max distances local ratio = (math.min(maxdistance, math.max(mindistance,distance)) - mindistance) / (maxdistance - mindistance)`

3.) using that 0-1 value to fade between two colors:Code: Select all

`-- adjust color color[1] = mincolor[1] * ratio + maxcolor[1] * (1.0-ratio) color[2] = mincolor[2] * ratio + maxcolor[2] * (1.0-ratio) color[3] = mincolor[3] * ratio + maxcolor[3] * (1.0-ratio)`

Gah, I feel dumb cuz i dont understand >< I'm going over it all and its just hurting my head :C Maybe its to advanced for me right now

The most I could manage is printing the difference, and I'm not even smart enough to know if it's printing a correct value

Code: Select all

```
function love.load()
rect1 = {0,0,32,32}
rect2 = {100,200,32,32}
end
function love.update()
dx = (rect1[1] + rect1[3]/2 - (rect2[1] + rect2[3]/2))
dy = (rect1[2] + rect1[4]/2 - (rect2[2] + rect2[4]/2))
local distance = math.sqrt(dx * dx + dy * dy)
print(distance)
end
function love.draw()
love.graphics.rectangle("fill", rect1[1], rect1[2], rect1[3], rect1[4])
love.graphics.rectangle("fill", rect2[1], rect2[2], rect2[3], rect2[4])
end
```

### Who is online

Users browsing this forum: No registered users and 25 guests