Page 2 of 2
Re: line with ellipse/circle collision
Posted: Thu Mar 01, 2018 2:50 pm
by NotARaptor
Hello!
Sorry, new here - first post and all that. I saw this thread and thought I'd give it a go.
Treating the ellipses as polylines, this code calculates the intersections of line segments and ellipses - it seems pretty efficient for most use-cases, but I'm sure it could be improved.
Screenshot:
- ellipses-and-segments.png (183.17 KiB) Viewed 4364 times
Code:
- main.lua
- (11.08 KiB) Downloaded 168 times
Re: line with ellipse/circle collision
Posted: Mon Mar 19, 2018 12:41 am
by p0co
Hi Guys,
I need a ball to go through a line, when it does I increase the player's score. Similar to a soccer goal, but the line is moving.
I dont want the ball to bounce off the line, I need it to go through it, but still trigger a collision so I can increase the players score.
I want to use physics. The ball has a body and shape of a circle - but how shall I do the line ?
I have considered not using physics but the maths calculations for this may seem over kill and slow the game down ?
How shall I do this ?
The game is attached. .. to play just click drag the mouse to move the white ball. between the red and blue ball to score the goal past that line. In the attached example, I far I have tried newEdgeShape for the line, but that doesnt seem to be working ...
Please help
Re: line with ellipse/circle collision
Posted: Mon Mar 19, 2018 6:08 am
by ivan
With "EdgeShape" you have to destroy and create the fixture each frame as the balls move around.
Luckily, this isn't very expensive as you are dealing with just one edge.
Re: line with ellipse/circle collision
Posted: Mon Mar 19, 2018 12:45 pm
by pgimeno
I wouldn't use collisions for this. Instead, I suggest using intersection of two segments. Let me explain.
While playing I ran into this situation:
- HappyMoon-shortshot.png (45.87 KiB) Viewed 4265 times
I fell short of crossing the line. If you consider a collision as scoring, you would be granting a point there. You should then ignore subsequent collisions until it stops colliding, in order to not grant more than one point every time.
My suggestion, however, is to score a point whenever the ball's centre crosses the line. To detect that, imagine the line between the ball's position in the previous frame and the ball's position in the current frame. If that (short) line segment crosses the goal line, make the player score. Here's an algorithm for detecting intersection of two line segments:
https://stackoverflow.com/questions/563 ... -intersect
Note however that in the case I ran into above, it is very easy to score multiple times, by making the shots very short so they cross the line.
Edit: One suggestion to prevent cheating like that is to score only when the goal line is crossed in one direction, e.g. with the blue ball on the left, and to
remove a point when it's crossed in the other direction. I've not done the math to confirm, but that can probably be detected using the sign of
rx
s.
Re: line with ellipse/circle collision
Posted: Tue Mar 20, 2018 8:59 am
by p0co
pgimeno wrote: ↑Mon Mar 19, 2018 12:45 pm
I wouldn't use collisions for this. Instead, I suggest using intersection of two segments. Let me explain.
My suggestion, however, is to score a point whenever the ball's centre crosses the line. To detect that, imagine the line between the ball's position in the previous frame and the ball's position in the current frame. If that (short) line segment crosses the goal line, make the player score. Here's an algorithm for detecting intersection of two line segments:
https://stackoverflow.com/questions/563 ... -intersect
Note however that in the case I ran into above, it is very easy to score multiple times, by making the shots very short so they cross the line.
Initially I wanted to use collisions, because I thought using my intersection function would be computationally too slow ??
Regarding the cheating aspect: I intend to swap the position of the white ball, with the blue or red, after each turn. So the play doesn't cheat by making short pushes back and forward.
So I don't need the centre of the ball as the point of collision with the line. As I eliminate cheating in other ways.
I need the edge of the ball to touch the line to score.
I have tried making the line a EdgeShape, but that doesn't seem to act like a line for my case.
Below is the code for the goal / line .. Can you please help? And many thanks in advanced, I hope to use shaders and make this look beautiful after this 1 hurdle is resolved.
Code: Select all
goal = {}
goal.x1 = 0
goal.y1 = 0
goal.x2 = 0
goal.y2 = 0
goal.message = "goal: "
goal.drawMessage = function (self)
love.graphics.print(self.message, 20, 60)
end
goal.body = love.physics.newBody(world, goal.x1, goal.y1, "dynamic")
goal.shape = love.physics.newEdgeShape( red.body:getX(),red.body:getY(), blue.body:getX(), blue.body:getY() )
goal.fixture = love.physics.newFixture(goal.body, goal.shape)
goal.fixture:setUserData("Goal")
goal.update = function(self)
self.x1 = red.body:getX()
self.y1 = red.body:getY()
self.x2 = blue.body:getX()
self.y2 = blue.body:getY()
end
goal.draw = function(self)
love.graphics.setColor(55, 150, 150)
love.graphics.setLineStyle( 'smooth' )
love.graphics.setLineWidth( 1 )
love.graphics.line( self.x1 , self.y1 , self.x2 , self.y2 )
love.graphics.setColor(250, 250, 250)
end
goal.updateMessage = function (self)
self.x1, self.y1, self.x2, self.y2 = goal.shape:getPoints( )
goal.message = "x1: " .. self.x1 ..
"\ny1: " .. self.y1 ..
"\nx2: " .. self.x2 ..
"\ny2: " .. self.y2 ..
"\n\n World" .. goal.body:getWorldPoints(goal.shape:getPoints()) .. "\n "
end
Re: line with ellipse/circle collision
Posted: Tue Mar 20, 2018 12:34 pm
by pgimeno
p0co wrote: ↑Tue Mar 20, 2018 8:59 am
Initially I wanted to use collisions, because I thought using my intersection function would be computationally too slow ??
I don't think so. You probably can sustain hundreds of such calculations per frame.
p0co wrote: ↑Tue Mar 20, 2018 8:59 am
Regarding the cheating aspect: I intend to swap the position of the white ball, with the blue or red, after each turn. So the play doesn't cheat by making short pushes back and forward.
Nice solution too. I like yours better than mine.
p0co wrote: ↑Tue Mar 20, 2018 8:59 am
So I don't need the centre of the ball as the point of collision with the line. As I eliminate cheating in other ways.
Well, that solution was not about cheating; my proposal about cheating had to do with crossing the line in one sense only. That solution was about solving the scoring problem. It's intuitive for players to score a goal when your ball's centre crosses the line. To me, just touching the line does not feel so much like a reason to score. It's also a very lightweight calculation and I still recommend it over using physics.
You can still make the collision detection the way you want, by finding the point that is closest to the line from the centre of the ball, checking that it's within the segment limits, and then measuring the distance and comparing it to the radius. That's also lightweight (not so much as the centre crossing one but still doable many times per frame).