Page 1 of 1

Getting distance

Posted: Sat Apr 09, 2016 4:13 am
by Vimm
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?

Re: Getting distance

Posted: Sat Apr 09, 2016 6:00 am
by zorg
The easiest solution would be to not use love.physics, and do this:

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.
But you can probably adapt this to your needs :3

Re: Getting distance

Posted: Sat Apr 09, 2016 3:50 pm
by substitute541
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.


Re: Getting distance

Posted: Sat Apr 09, 2016 7:13 pm
by Vimm
zorg wrote:The easiest solution would be to not use love.physics, and do this:

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.
But you can probably adapt this to your needs :3

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)
, 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?

Re: Getting distance

Posted: Sat Apr 09, 2016 7:23 pm
by s-ol
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 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: also, you create variables c1 and c2 then do

Code: Select all

local distance = math.sqrt(c1^2.0 + c2^2.0)
, 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?
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.

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)
part of zorg's code.

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

Posted: Sat Apr 09, 2016 7:54 pm
by Vimm
s-ol wrote:
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 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: also, you create variables c1 and c2 then do

Code: Select all

local distance = math.sqrt(c1^2.0 + c2^2.0)
, 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?
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.

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)
part of zorg's code.

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)
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 bad :rofl:

Re: Getting distance

Posted: Sat Apr 09, 2016 9:58 pm
by zorg
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.

Re: Getting distance

Posted: Sun Apr 10, 2016 12:36 am
by substitute541
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.
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.


Re: Getting distance

Posted: Sun Apr 10, 2016 3:53 am
by zorg
(I did, honestly) :3

Re: Getting distance

Posted: Mon Apr 11, 2016 8:43 pm
by Vimm
s-ol wrote:
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 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: also, you create variables c1 and c2 then do

Code: Select all

local distance = math.sqrt(c1^2.0 + c2^2.0)
, 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?
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.

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)
part of zorg's code.

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