how to make rotate polygon on key in pygame? - pygame

I am trying to make my polygon rotate able. But when I input new_point the report is new_point aren't define. This is giving me a headache
def xoay_hinh(key):
lx, ly = zip(*hinh)
min_x, min_y, max_x, max_y = min(lx), min(ly), max(lx), max(ly)
new_hinh = hinh
if key[pygame.K_r]:
cx = ((max_x - min_x)/2) + min_x
cy = ((max_y - min_y)/2) + min_y
for point in hinh and for new_point in new_hinh :
new_point[0] = cy - point[1]
new_point[1] = cy + point[0] - cx
point[0] = new_point[0]
point[1] = new_point[1]
T had try to used pygame.tranfrom.rotate() and replace "new_point" with different value but the program still refuse to run

There is no need to create a pygame.Surface and to use pygame.transform.rotate to rotate the points of a polygon. You can use pygame.math.Vectore2.rotate tor create a rotated list of points.
define the pivot point (e.g. center of the polygon)
calculate the vectors from the pivot point to the points of the polygon
use pygame.math.Vectore2.rotate to rotate the vectors
add the pivot point to the rotated vectors
def rotate_points_around_pivot(points, pivot, angle):
pp = pygame.math.Vector2(pivot)
rotated_points = [
(pygame.math.Vector2(x, y) - pp).rotate(angle) + pp for x, y in points]
return rotated_points
Minimal example:
import pygame
def rotate_points_around_pivot(points, pivot, angle):
pp = pygame.math.Vector2(pivot)
rotated_points = [
(pygame.math.Vector2(x, y) - pp).rotate(angle) + pp for x, y in points]
return rotated_points
def draw_rotated_polygon(surface, color, points, angle, pivot=None):
if pivot == None:
lx, ly = zip(*points)
min_x, min_y, max_x, max_y = min(lx), min(ly), max(lx), max(ly)
bounding_rect = pygame.Rect(min_x, min_y, max_x - min_x, max_y - min_y)
pivot = bounding_rect.center
rotated_points = rotate_points_around_pivot(points, pivot, angle)
pygame.draw.polygon(surface, color, rotated_points)
pygame.init()
window = pygame.display.set_mode((250, 250))
clock = pygame.time.Clock()
pivot = (125, 125)
size = 90
points = [(0, -1), (-0.8660, 0.5), (0.8660, 0.5)]
points = [(pivot[0] + x * size, pivot[1] + y * size) for x, y in points]
angle = 0
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
key = pygame.key.get_pressed()
if key[pygame.K_r]:
angle += 1
window.fill("black")
draw_rotated_polygon(window, "white", points, angle, pivot)
pygame.display.flip()
pygame.quit()

Related

Why the Loss function does not decrease significantly in Flux.jl

After trying some optimizations on activation function and epochs value , it is not possible to fit the model to y data which is a function of the input data.
using Flux, Plots, Statistics
x = Array{Float64}(rand(5, 100));
w = [diff(x[1,:]); 0]./x[1,:];
y1 = cumsum(cos.(cumsum(w)));
scatter(y1)
y = reshape(y1, (1, 100));
data = [(x, y)];
model = Chain(Dense(5 => 100), Dense(100 => 1), identity)
model[1].weight;
loss(m, x, y) = Flux.mse(m(x), y)
Flux.mse(model(x), y)
Flux.mse(model(x), y) == mean((model(x) .- y).^2)
opt_stat = Flux.setup(ADAM(), model)
loss_history = []
epochs = 10000
for epoch in 1:epochs
Flux.train!(loss, model, data, opt_stat)
# print report
train_loss = Flux.mse(model(x), y)
push!(loss_history, train_loss)
println("Epoch = $epoch : Training Loss = $train_loss")
end
ŷ = model(x)
Flux.mse(model(x), y)
Y = reshape(ŷ, (100, 1));
scatter(Y)

Octave changes scale of y axis when I change the x-axis

When I used this code, it plots two functions like this:
a = 2;
t0 = 1;
N = 100;
epsilon = 1e-5;
function t = metodoDeNewton(a, t0, N, epsilon)
t = zeros(1, N+1);
t(1) = t0;
for i = 1:N
t(i+1) = t(i) - (t(i).^2 - (a - sin(t(i)))) ./ (2 .* t(i) - cos(t(i)));
if abs(t(i+1) - t(i)) < epsilon
break;
endif
endfor
endfunction
t = metodoDeNewton(a, t0, N, epsilon);
x = 0:0.01:1;
y1 = t;
y2 = a - sin(t);
l = plot(x, y1, x, y2);
legend({'g(a)', 'h(a)'});
xlabel('a');
ylabel('y');
But, when I try to change the x to x = 0:0.01:0.2 the graph's y-axis scale changes and I'm no longer able to see the functions I believe.
How can I fix this, any help would be appreciated!

How do I get the percentage of a colour in a screen in pygame?

I am new to pygame and trying to create a 'splatoon' like game, I got the basic elements ready but I don't know how to calculate the percentage of the screen. Do I individually scan each pixel using get_at or is there an easier method to calculate it?
Here is my code:
import pygame
import sys
black = (0,0,0)
white = (255, 255, 255)
silver = (192, 192, 192)
aqua = (0, 255,255)
x = 10
y =490
a = 490
b = 10
vel = 1
pygame.init()
FPS = 60
fpsClock = pygame.time.Clock()
win = pygame.display.set_mode((500,500))
time = pygame.time.get_ticks()
while True:
seconds = (pygame.time.get_ticks())/1000
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if seconds <= 10:
keys = pygame.key.get_pressed()
color = black
if keys[pygame.K_d] and x < 490:
x += vel
if keys[pygame.K_RIGHT] and a < 490:
a += vel
if keys[pygame.K_a] and x > 0:
x -= vel
if keys[pygame.K_LEFT] and a > 0:
a -= vel
if keys[pygame.K_w] and y > 0:
y -= vel
if keys[pygame.K_UP] and b > 0:
b -= vel
if keys[pygame.K_s] and y < 490:
y += vel
if keys[pygame.K_DOWN] and b < 490:
b += vel
if keys[pygame.K_e]:
pygame.draw.rect(win, aqua, (x-20,y-20,50,50))
if keys[pygame.K_SPACE]:
pygame.draw.rect(win, silver, (a-20,b-20,50,50))
if keys[pygame.K_p]:
win.fill((0,0,0))
pygame.draw.rect(win, aqua, (x,y,10,10))
pygame.draw.rect(win, silver, (a,b,10,10))
pygame.display.update()
fpsClock.tick(FPS)
else:
break
I think you can use a function like this, using pygame.Surface.get_at():
def get_percentage(color, step=1):
width, height = screen_size
total_number_of_pixels = width * height
number_of_pixels = 0
for x in range(0, width, step):
for y in range(0, height, step):
if screen.get_at((x, y)) == color:
number_of_pixels += 1
percentage = number_of_pixels / total_number_of_pixels * 00
return percentage
But because it can considerably slow down the code, you may store the percentage and call this function only when the percentage is updated (for example if a player attacks).
And you can change the step var in the code above to get the percentage more roughly (and quicker).

Surface plot of equally spaced grid of overlapping Gaussians not plotting correctly?

I am attempting to make a surface plot in Octave based on a bunch of overlapping, offset curves. the function should be treating x and y identically but I am not seeing that in the final plot, rather it has ridges running along one axis. I cant tell if this is a plotting error or something else wrong with my code. am hoping you can provide some help/insight.
Plot with ridges following one axis
Thanks
clear;
graphics_toolkit gnuplot
V = 2500; %scan speed in mm
rr = 200000; %rep rate in Hz
Qsp = 1; %pulse energy
pi = 3.14159;
ns = 1; %scan number
w = 0.0125; %Gaussian radius in mm
dp = 0.0125; %lateral pulse distance in mm
dh = 0.0125; %hatch pitch in mm
xmax = 0.2; %ablation area x in mm
ymax = 0.2; %ablation area y in mm
np = round(xmax/dp);
nh = round(ymax/dh);
points = 50;
cof = ns*2*Qsp/(pi*w^2);
N = [0:1:np];
M = rot90([0:1:nh]);
for i = 1:points
for j = 1:points
x = (i-1)*xmax/(points-1);
y = (j-1)*ymax/(points-1);
k = exp(-(2*(x-N*dp).^2+(y-M*dh).^2)/(w^2));
H(i,j) = cof*sum(sum(k));
endfor
endfor
ii = [1:1:points];
jj = ii;
xx = (ii-1)*xmax/(points-1);
yy = (jj-1)*ymax/(points-1);
surf(xx,yy,H);
I find it helpful to space out components of complex expressions.
k = exp(-(2*(x-N*dp).^2+(y-M*dh).^2)/(w^2));
It's too hard to read with so many parentheses.
k = exp(
-(
2*(x-N*dp).^2 + (y-M*dh).^2
) / (w^2)
);
Do you see it already?
k = exp(
-(
2 * (x-N*dp).^2
+
(y-M*dh).^2
) / (w^2)
);
The x component gets multiplied by two, but the y component doesn't.

create a vector with size x and value f(x) in octave

I have to generate a dataset of N data points, which are defined as t_n=f(x_n)+e, where e is drawn from normal distribution and f(x) is a nonlinear function.
For example, i have a function f(x)=x²+2x+10, how can i fill a vector v, such:
x = 1:1:100;
v = create(f(x)+normrnd(0,1),x);
Thank you
There are many methods to do this. Here I show you how to do it with anonymous functions http://www.gnu.org/software/octave/doc/v4.0.1/Anonymous-Functions.html#Anonymous-Functions
f = #(x) polyval ([1 2 10], x)
x = 1:100;
v = f(x) + normrnd (0, 1, size (x));
Or without a function:
x = 1:100;
v = x.^2 + 2.*x + 10 + normrnd (0, 1, size (x));
I've adjusted x here so that the noise is visible:
x = linspace (-3, 3);
v = f(x) + normrnd (0, 1, size (x));
plot (x, v)
grid on