If I have a ball in tkinter with radius 20 at coordinates x,y. What's the best method to find out if another object is touching it or partially overlapping it. I tried equating the coordinates of the two objects however that would only happen in very specific cases. Is there a away I can build a list that contains all the coordinates the ball occupies using its center coordinates and its radius?
Thank you
The circle's circumference consists of all the points that are exactly 20 units from the center. Therefore, if the distance from an edge of your object to the circle's center is less than 20, it will be inside the circle. If it's exactly 20, it will be touching the circle.
Related
So after I've done object detection, I have a few overlapping 2d rectangles, and I want to find size of the area outside of all the rectangles I've created, which has (xyxy) coordinates on each one. How do I find size of area outside that boxes in python?
enter image description here
I have tried to calculate the area by adding the sizes of all the bounding boxes then the sum will be used to subtract the size from the input image. However, it is still constrained by overlapping square lengths so that the measurement is not accurate.
from bbox import BBox2D
box1 = BBox2D([0.20212765957446807, 0.145625, 0.24822695035460993, 0.10875])
box2 = BBox2D([0.6693262411347518, 0.146875, 0.31382978723404253, 0.06875])
print(box2.height * box2.width)
print(box1.height * box1.width)
Try this one.
or simply u can
def _getArea(box):
return (box[2] - box[0]) * (box[3] - box[1])
This should do the trick. Structure of Box: [xmin,ymin,xmax,ymax]
To find the area outside all of the boxes, you will need to do the following things.
Find the area of the entire image
Find the area of all of the rectangles (including overlapping area)
Find the total overlapping area
Subtract the total overlapping area from the total area of the rectangles
Subtract the rectangle area without overlap from the area of the entire image
To find the total overlapping area, you will need to loop through every rectangle on the screen and check if it is overlapping. If it is overlapping another rectangle you will need to find the corners that are overlapping each other. For example in your image, the top left and middle rectangles are overlapping. The two corners you need would be the bottom right corner of the top left rectangle and the top left corner of the middle rectangle. You can then find the area of the rectangle that is made by the overlap.
If you add a little more information in your question, I could type out a simple function that could do this but right now I don't know all the specifications.
I'm looking for a way to split a number of images into proper rectangles. These rectangles are ideally shaped such that each of them take on the largest possible size without containing a lot of white.
So let's say that we have the following image
I would like to get an output such as this:
Note the overlapping rectangles, the hole and the non axis aligned rectangle, all of these are likely scenario's I have to deal with.
I'm aiming to get the coordinates describing the corner pieces of the rectangles so something like
[[(73,13),(269,13),(269,47)(73,47)],
[(73,13),(73,210),(109,210),(109,13)]
...]
In order to do this I have already looked at the cv2.findContours but I couldn't get it to work with overlapping rectangles (though I could use the hierarchy model to deal with holes as that causes the contours to be merged into one.
Note that although not shown holes can be nested.
A algorithm that works roughly as follow should be able to give you the result you seek.
Get all the corner points in the image.
Randomly select 3 points to create a rectangle
Count the ratio of yellow pixels within the rectangle, accept if the ratio satisfy a threshold.
Repeat 2 to 4 until :
a) every single combination of point is complete or
b) all yellow pixel are accounted for or
c) after n number of iteration
The difficult part of this algorithm lies in step 2, creating rectangle from 3 points.
If all the rectangles were right angle, you can simply find the minimum x and y to correspond for topLeft corner and maximum x and y to correspond for bottomRight corner of your new rectangle.
But since you have off axis rectangle, you will need to check if the two vector created from the 3 points have a 90 degree angle between them before generating the rectangle.
I want to place N circles with given, common radius in the rectangle of given size, such that circles are not overlapping in Python. My current solutions are:
1) to create a set of every point in the space and remove from it points that will cause overlapping before generating next circle (but it's slow when the rectangle is big).
2) to draw the center of balls from the set of not-overlapping points (e.g. every 2r + const) (but the positions are not random enough here).
Do you have other, more efficient ideas?
so the most efficient packing in 2D is hexagonal packing and you can just hard code your program to give that packing for circles
read more about it here : https://en.wikipedia.org/wiki/Circle_packing
I am using pygame to make a simple game. I am having issues with circle collisions. I am getting the following error:
"AttributeError: 'pygame.Rect' object has no attribute 'rect'"
Here is the particular code I am having issues with below:
if pygame.sprite.collide_circle(hero_circle, enemy_circle):
gameover()
Use pygame.mask to create a collision mesh for your objects and use the mesh to do collision detections.
In more detail:
Create an image file for both of your circles and set the bg color to something you will not use anywhere else.
Set that color to "transparent" in your image editor.
Import the images.
Create a mesh for them with pygame.mask and set it to make transparent pixels non-collidable.
Use the generated mask as your collision detection mesh.
PROFIT
(Technically this is just doing collision detection of a circle shaped area on a rectangle, but who cares!)
pygame.draw.rect()
draw a rectangle shape
rect(Surface, color, Rect, width=0) -> Rect
Draws a rectangular shape on the Surface. The given Rect is the area of the rectangle. The width argument is the thickness to draw the outer edge. If width is zero then the rectangle will be filled.
Keep in mind the Surface.fill() method works just as well for drawing filled rectangles. In fact the Surface.fill() can be hardware accelerated on some platforms with both software and hardware display modes.
The best way I've found to check circle collision detection is to calculate the distance between the center points of two circles. If the distance is less than the sum of the two circle's radii, then you've collided.
Just like how gmk said it but if your are using circles instead of rectangles, you should use this pygame function :
pygame.draw.circle(surface, color, center_point, radius, width)
This draws a circle on your surface (which would go in the surface area). Clearly the color requires a list of numbers (RGB anyone?). Your center_point decides the location of your circle since it will be the location of the center of your circle. The radius will need a number to set the radius of the circle (using the number like 25 will set your radius at 25 pixels/diameter at 50 pixels). the width section is optional as it sets the thickness of the perimeter of your circle (having 0 will have none at all). If you are not using circles, you should change your title... But anyways, I hope this helps you!
I'm having some trouble dealing with drawing perfect concentric circles, or perfect spacing between a circle. I'm using John Zelle's graphics library but the problem I'm dealing with is more conceptual (and graphics in general) than it is with the limitations of the Library. When I draw a circle w/ a 200 pixel radius, and I try to create 50 perfect circles within the main circle the library doesn't take into account the outline of a circle, which means I don't get perfect partitions. More circles I add, the further away I get from perimeter of the main circle. The 50 circles are evenly spaced apart, the problem is they come short of the main circle.
for x in range(1, numPartition+1): #numPartitions is 50, for 50 circles
cInsideRadius = mainCirRadius/(numPartition+1)*x
c = circle(Point(x,y),Point(x,y), cInsideRadius) #where cInsideRadius is the radius of circle c
c.draw(window)
Figured it out, has to do with partition sizes being casted as ints and not floats.
Figured it out, has to do with partition sizes being casted as ints and not floats.