python draw pie shapes with colour filled - python

I am trying to draw a pie shape with filled colour. I've tried to do this in different ways. Here's the code:
ball = pygame.draw.circle(self.screen, self.pink, self.pos, self.r, 0)
pygame.gfxdraw.pie(self.screen, 60,60, 40, 0, 90,(0,255,0))
pygame.gfxdraw.arc(self.screen, 60,60, 40, 180, 270,(0,255,255))
pygame.draw.arc(self.screen, (255,0,255),ball,0, math.pi/4, ball.width/2)
The output image is like:
I want the pie shapes filled with colour, as the magenta coloured shape does. I used the arc function and set the line with = the radius to achieve this (4th line in the code). However, the colour isn't evenly filled. I also tried to draw a pie shape (2nd line in the code) However, I cannot find a way to fill the colour...
Thank you very much for your help!

You can just draw a sufficiently fine polygon (e.g in one degree intervals):
import math
import pygame
# Center and radius of pie chart
cx, cy, r = 100, 320, 75
# Background circle
pygame.draw.circle(screen, (17, 153, 255), (cx, cy), r)
# Calculate the angle in degrees
angle = val*360/total
# Start list of polygon points
p = [(cx, cy)]
# Get points on arc
for n in range(0,angle):
x = cx + int(r*math.cos(n*math.pi/180))
y = cy+int(r*math.sin(n*math.pi/180))
p.append((x, y))
p.append((cx, cy))
# Draw pie segment
if len(p) > 2:
pygame.draw.polygon(screen, (0, 0, 0), p)

Related

How do I draw a matrix round in python?

I have a matrix filled with 0 and 1. I would like to draw it round instead of square. That is, divide the circle into sectors and color them according to the matrix as in this picture:
Each value in this array corresponds to the color that should be filled in the image area. I painted the area pink for clarity:
I managed to create pie slices that I can shade, which works for the sections in circle b for example, but not for the other two:
from PIL import Image, ImageDraw
x_center = 400 // 2
y_center = 400 //2
img = Image.new('RGBA', (400, 400), 'white') Here's what happened
idraw = ImageDraw.Draw(img)
idraw.pieslice([x_center-100, x_center-100,
y_center + 106, y_center + 106], 225, 315, fill='blue')
Here's what happened:
Do you know how to do it in matplotlib or plotly? Theoretically, I understand how to do it, practically-no... Can you help me please??

How to fill color within cv2.ellipse figure?

I have this code. Which takes image and draws ellipse over the defined point.Like this sample. But i am struggling to figure out how can i fill color in it?
def annotate_image(annotations, i):
file_name = annotations[i][0]
PATH= "/content/content/train/Class1_def/"+file_name+'.png'
img=cv2.imread(PATH)
#print(img.shape)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
semi_major= int(float(annotations[i][1]))
semi_minor= int(float(annotations[i][2]))
rotation= int(float(annotations[i][3]))
x_pos_ellip= int(float(annotations[i][4]))
y_pos_ellip= int(float(annotations[i][5]))
center_coordinates= (x_pos_ellip, y_pos_ellip)
axesLength= (semi_major,semi_minor)
angle= int(float(rotation))
startAngle = 0
endAngle = 360
# Red color
color = (255, 0, 0)
# Line thickness
thickness = 2
cv2.ellipse(img, center_coordinates, axesLength,
angle, startAngle, endAngle, color, thickness)
return img
Use a negative value for the thickness parameter. From the docs on cv.ellipse():
thickness Thickness of the ellipse arc outline, if positive. Otherwise, this indicates that a filled ellipse sector is to be drawn.
This is true of all of OpenCV's drawing functions for closed shapes. If you want both a fill and a separate stroke, simply draw the filled ellipse first, then the stroke on top.
Set thickness = -1, this will fill the color in it.

black area between overlapped circles in opencv - python

I am implementing "Bubbles algorithm" for classification recognition analysis.
in this algorithm, we have to make mask with gaussian circles.
the center of circles would be 1(255) and it will decrease over the radius which will be 0.
i have problem when i put circles on each other for creating the mask, it will put a black line between circles and i can not remove it.
this is my code:
def make_gaussian(circle_center, Gaussian_base):
for t in range(circle_center[1] - radius, circle_center[1] + radius):
for tt in range(circle_center[0] - radius, circle_center[0] + radius):
distance = int(compute_distance(tt, circle_center[0], t, circle_center[1]))
if distance < radius :
value = int(((radius - distance) * (1 / radius)) * 255)
if Gaussian_base[t][tt].mean() < value:
Gaussian_base[t][tt] = [value, value, value]
return Gaussian_base
Gaussian_base = np.zeros((height, width, 3), np.uint8)
for s in centers:
#xmin, ymin, xmax, ymax
Gaussian_base = make_gaussian(s, Gaussian_base)
cv2.imwrite('gaussianMask.jpg', Gaussian_base)
you can use this list as centers:
centers = [(139, 102), (223, 193), (94, 385), (205, 301), (90, 147), (190, 209), (45, 349), (193, 259), (110, 343), (159, 99)]
and the output is like this:
enter image description here
the problem is the black line(area) between two overlapped circles which should be removed and the joint area should be continous.
Try this...
def make_gaussian(circle_center, Gaussian_base):
for t in range(circle_center[1] - radius, circle_center[1] + radius):
for tt in range(circle_center[0] - radius, circle_center[0] + radius):
distance = int(compute_distance(tt, circle_center[0], t, circle_center[1]))
if distance < radius :
value = int(((radius - distance) * (1 / radius)) * 200)
#if Gaussian_base[t][tt].mean() < value:
Gaussian_base[t][tt] += np.array([value, value, value], dtype=np.uint8)
return Gaussian_base
the "black line" in your posted image between balls is an optical illusion. it is a local minimum and your eyes recognize that.
open your image in an image editor. take the color picker. move along a ball and into the "black line". the indicated color/brightness moves smoothly. it doesn't dip and it's not black.

Calculate angles that are in degrees (clockwise) to radians (counter clockwise)

First, I am aware of how converting degrees in radians.
I need to draw an arc given a coordinate, radius, and two angles in degrees clockwise in pygame. For example:
point = (50, 50)
startAngle = 320
endAngle = 140
should draw something like
and
point = (50, 50)
startAngle = 90
endAngle = 180
should draw something like
etc.
I have tried reverting the angle (i.e. 360 - angle) but pygame draws the arc in reverse; instead of a 45⁹ arc in the last image, I get a 270⁹ arc that is the complement of what I want.
I guess I'm having a brain fart day because I can't figure this out. Thank you!
Edit : I may have an answer, though I'm not sure if it is a good one. If I reverse the angles and negate them, it seems to draw them correctly clockwise. For example, given the first example :
point = (50, 50)
startAngle = 360 - 140
endAngle = 360 - 320
seems to correctly draws the arc where expected.
If you want to draw an clockwise arc, then you've to invert the angles and you've to swap the start and end angle:
def clockwiseArc(surface, color, point, radius, startAngle, endAngle):
rect = pygame.Rect(0, 0, radius*2, radius*2)
rect.center = point
endRad = math.radians(-startAngle)
startRad = math.radians(-endAngle)
pygame.draw.arc(surface, color, rect, startRad, endRad)
e.g.:
clockwiseArc(window, (255, 0, 0), (150, 70), 50, 300, 140)
clockwiseArc(window, (255, 0, 0), (300, 70), 50, 90, 180)

Python reflect image along each sides of the triangle

I have created a triangle positioned in the centre of the screen.
from PIL import Image, ImageDraw
GRAY = (190, 190, 190)
im = Image.new('RGBA', (400, 400), WHITE)
points = (250, 250), (100, 250), (250, 100)
draw = ImageDraw.Draw(im)
draw.polygon(points, GRAY)
How do I duplicate this image and reflect it along each sides of the triangle at different random points. For example...
Plan: First find a random point on the edge of the big triangle where to put a smaller one, and then rotate it so it fits properly on the edge.
Suppose we can access the points of the triangle with something like this
triangle.edges[0].x,
triangle.edges[0].y,
triangle.edges[1].x,
etc
We can then find an arbitrary point by first selecting an edge, and "walk a random distance to the next edge":
r = randInt(3) # random integer between 0 and 2
first_edge = triangle.edges[r]
second_edge = r == 2 ? triangle.edges[0] : triangle.edges[r + 1]
## The next lines is kind of pseudo-code
r = randFloat(1)
random_point = (second_edge - first_edge)*r + first_edge
Our next problem is how to rotate a triangle. If you have done some algebra you might recognise this:
def rotatePointAroundOrigin(point, angle):
new_point = Point()
new_point.x = cos(angle)*point.x - sin(angle)*point.y
new_point.y = sin(angle).point.x + cos(angle)*point.y
return new_point
(see https://en.wikipedia.org/wiki/Rotation_matrix)
In addition to this you need to determine just how much to rotate the triangle, and then apply the function above to all of the points.

Categories

Resources