Getting distance

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Vimm
Party member
Posts: 113
Joined: Wed Mar 16, 2016 8:14 pm

Getting distance

Post 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?
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Getting distance

Post 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
Me and my stuff :3True 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.
User avatar
substitute541
Party member
Posts: 484
Joined: Fri Aug 24, 2012 9:04 am
Location: Southern Leyte, Visayas, Philippines
Contact:

Re: Getting distance

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

Currently designing themes for WordPress.

Sometimes lurks around the forum.
User avatar
Vimm
Party member
Posts: 113
Joined: Wed Mar 16, 2016 8:14 pm

Re: Getting distance

Post 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?
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Getting distance

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

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
Vimm
Party member
Posts: 113
Joined: Wed Mar 16, 2016 8:14 pm

Re: Getting distance

Post 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:
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Getting distance

Post 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.
Me and my stuff :3True 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.
User avatar
substitute541
Party member
Posts: 484
Joined: Fri Aug 24, 2012 9:04 am
Location: Southern Leyte, Visayas, Philippines
Contact:

Re: Getting distance

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

Currently designing themes for WordPress.

Sometimes lurks around the forum.
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Getting distance

Post by zorg »

(I did, honestly) :3
Me and my stuff :3True 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.
User avatar
Vimm
Party member
Posts: 113
Joined: Wed Mar 16, 2016 8:14 pm

Re: Getting distance

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

Who is online

Users browsing this forum: Google [Bot] and 21 guests