draw arc with different arguments - python

I'm using Pygame to draw some shapes on the screen.
The problem is, I get those shapes from a different application, which exports a txt with the parameters of the arc, like this:
ARC1:
start_x=,
start_y=,
center_x=,
center_y=,
end_x=,
end=y=,
radius=,
start_angle=,
end_angle=
These are the parameters pygame needs to draw an arc:
surface (Surface) -- surface to draw on
color (Color or int or tuple(int, int, int, [int])) -- color to draw with, the alpha value is optional if using a tuple (RGB[A])
rect (Rect) -- rectangle to indicate the position and dimensions of the ellipse which the arc will be based on, the ellipse will be centered inside the rectangle
start_angle (float) -- start angle of the arc in radians
stop_angle (float) -- stop angle of the arc in radians
This function asks a rect, is there a way to calculate the rect with the parameters I have (from the txt) and keep its original shape and position?

The rect argument of pygame.draw.arc specifies the bounding rectangle of the circle the arc is on:
rect -- rectangle to indicate the position and dimensions of the ellipse which the arc will be based on, the ellipse will be centered inside the rectangle
The bounding rectangle of a circle with a given center and radius is:
bounding_rect = pygame.Rect(center_x-radius, center_y-radius, radius*2, radius*2)

Related

pygame: mask non-image type surfaces

I know how to mask images. But if I simply want to create a circle and mask it, it would be annoying to create an image of a simple circle outside of my code, especially when I need to create different kinds of circles. Appearantly you can create Rect objects in pygame but there is no class Circle.
pygame.mask.from_surface requires a surface. Can I pass a non-image type surface as a parameter? If so how can I mask circles and/or other objects?
Here's something I imagined which obviously throws an error:
circle = pygame.Circle((10, 10), 5) # (center coordinates), radius
pygame.mask.from_surface(circle)
There is no way to create a circular mask directly. See pygame.mask. You need to draw a circle on a Surface. Create a function that creates a Surface and draw a circle on the Surface:
def circleSurface(color, radius):
shape_surf = pygame.Surface((radius * 2, radius * 2), pygame.SRCALPHA)
pygame.draw.circle(shape_surf, color, (radius, radius), radius)
return shape_surf
Create the Mask from the Surface:
circle = circleSurface((255, 255, 255), 5) # (center coordinates), radius
pygame.mask.from_surface(circle)
However, if you want to use a circle to clip an area of the display, see the answers to the following questions:
how to make circular surface in PyGame
How to fill only certain circular parts of the window in PyGame?

Finding the center of an image to define a hitbox

I'm trying to select the center of my image to make a hitbox some pixels around it.
I was able to inflate() the hitbox to make it the right size, but it always uses the top left corner of the image. This is fine when i'm moving left, but when i turn right it goes away from the character (in the image the character is dragging a sword, so it goes way off center).
I've been reading about Vector2, pos and offset, but i can't get it to work.
In conclusion i need to learn a way to find the center of my image in order to place it's hitbox a few pixels to each side. Either that or how to "shift" the corner the hitbox uses so it's always in the front of the char.
Use a pygame.Rect object. Get the rectangle from the pygame.Surface object (image) and set the top left corner position (x, y) of the rectangle. e.g.:
rect = image.get_rect()
rect.topleft = (x, y)
respectively
rect = image.get_rect(topleft = (x, y))
pygame.Rect provides a lot of virtual attributes, which can be used to retrieve the corners, borders, center and size of the rectangle. .center returns the center of the rectangle:
center_x, center_y = rect.center

Drawing a rotating rectangle around shapely polygon

i have polygon coordinates and i have plotted a polygon using PolygonPatch. Next up, using moments i have center coordinates (x,y) , height and width(X,Y) and rotation angle (theta). using these parameters i want draw the bounding rectangle around my polygon . i can draw these rotated rectangle using opencv
rect = cv2.minAreaRect(cnt)
box = cv2.cv.BoxPoints(rect)
box = np.int0(box)
cv2.drawContours(im,[box],0,(0,0,255),2)
but this only works when i am working on images not on shapley polygon patch. Is there a way i can draw the rotated rectangle around ploygonpatch without converting them to images.

Pygame circle collision?

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!

OpenCV, area between two curves

I work with OpenCV library in Python.
The question is how to select in separate roi the area across two curves?
Curves are defined by two quadric polynoms.
I want to find count of black pixels at the area restricted between curve 1 and curve 2
You can create mask by drawing ellipse, but you should have the following data from your equation,
center – Center of the ellipse (here I used centre of image).
axes – Half of the size of the ellipse main axes (here I used image size/2 and image size/4 respectively for both curve).
angle – Ellipse rotation angle in degrees, (here I used 0)
startAngle – Starting angle of the elliptic arc in degrees. (here I used 0)
endAngle – Ending angle of the elliptic arc in degrees.(here I used -180)
If you got the above data for both curve, you can simply draw ellipse with thickness=CV_FILLED like,
First draw largest ellipse with color=255.
Now draw second ellipse with color = 0.
See an example,
Mat src(480,640,CV_8UC3,Scalar(0,0,0));
ellipse(src,Point(src.cols/2,src.rows/2), Size (src.cols/2,src.rows/2), 0, 0,-180,Scalar(0,0,255), -1,8, 0);
ellipse(src,Point(src.cols/2,src.rows/2), Size (src.cols/4,src.rows/4), 0, 0,-180,Scalar(0,0,0), -1,8, 0);
Draw it on a single channel image, if you want to use it as mask.
Edit:-
To find the area, draw above to single channel image with color=255.
Then use countNonZero to get white pixel count.

Categories

Resources