Pygame not rendering 3d cube well [duplicate] - pygame

This question already has answers here:
Pygame rotating cubes around axis
(1 answer)
Does PyGame do 3d?
(13 answers)
Closed 5 months ago.
I am trying to build a rotating 3d cube without using any external python 3d module.
This is my code:
import pygame
WIDTH, HEIGHT = 700, 500
win = pygame.display.set_mode((WIDTH, HEIGHT))
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
points = [
[100, 100],
[200, 100],
[100, 200],
[200, 200],
[100, 100],
[200, 100],
[100, 190],
[100, 100],
[200, 100],
[100, 190],
[100, 100],
[200, 100],
[100, 190]
]
joining = [
(0, 1),
(0, 2),
(1, 3),
(2, 3),
(1, 4),
(2, 6),
(4, 6),
(4, 7),
(6, 9),
(7, 9),
(7, 10),
(9, 12),
(10, 12)
]
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
win.fill(WHITE)
if points[0][0] <= points[3][0]:
points[0][0] += 0.1
points[2][0] += 0.1
points[3][1] -= 0.03
points[6][1] += 0.009
elif points[4][0] <= points[0][0]:
points[4][0] += 0.1
points[6][0] += 0.1
points[2][1] -= 0.03
points[9][1] += 0.009
points[1][0] -= 0.1
points[3][0] -= 0.1
points[3][1] += 0.001
else:
points[7][0] += 0.1
points[9][0] += 0.1
points[6][1] -= 0.03
points[12][1] += 0.009
for point in points:
pygame.draw.circle(win, BLACK, point, 2)
for join in joining:
pygame.draw.line(win, BLACK, points[join[0]], points[join[1]])
pygame.display.flip()
pygame.quit()
The cube is not working fine. Can i have a more efficient way of drawing this cube in python without using any external module like OpenGl or something like that.
Running the code is advised to check what i am saying.

Related

Text doesn't display on the title screen button

I've been having trouble trying to display the title menu text when making a game. I'm trying to display the font on the button so that when I hover my mouse over the button, the font stays on the screen.
import pygame
pygame.init()
background_colour = (33, 37, 49)
screen = pygame.display.set_mode((1000, 600))
pygame.display.set_caption('A Game')
screen.fill(background_colour)
game_font = pygame.font.Font('JetBrainsMono-Regular.ttf', 50)
game_name = game_font.render('a game', True, (255, 255, 255))
game_name = pygame.transform.scale2x(game_name)
game_name_rect = game_name.get_rect(center=(500, 300))
pygame.draw.rect(screen, (38, 44, 60), game_name_rect)
running = True
title_screen = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if title_screen is True:
screen.blit(game_name, game_name_rect)
if not game_name_rect.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen, (38, 44, 60), game_name_rect)
if game_name_rect.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen, (58, 64, 80), game_name_rect)
pygame.display.update()
You need to draw the text after the rectangle:
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if title_screen is True:
color = (38, 44, 60)
if game_name_rect.collidepoint(pygame.mouse.get_pos()):
color = (58, 64, 80)
pygame.draw.rect(screen, color, game_name_rect)
screen.blit(game_name, game_name_rect)
pygame.display.update()

train yolov3 by mmdetection with VOCstyle-dataset

When I try to train yolo3 with command
python mmdetection/tools/train.py config/yolo-darknet53.py
and everything goes ok until first epoch begin and error happens that
it says "ValueError: need at least one array to concatenate" I am searching for a long time on net. But no use. Please help or try to give some ideas how to achieve this.
here is the yolo3 configuration file
#!user/bin/env python3
# -*- coding: utf-8 -*-
_base_ = '../mmdetection/configs/_base_/default_runtime.py'
classes = ('hand',)
# model settings
model = dict(
type='YOLOV3',
pretrained='D:/workplace/srtp/handdetection/checkpoints/darknet53-a628ea1b.pth',
backbone=dict(type='Darknet', depth=53, out_indices=(3, 4, 5)),
neck=dict(
type='YOLOV3Neck',
num_scales=3,
in_channels=[1024, 512, 256],
out_channels=[512, 256, 128]),
bbox_head=dict(
type='YOLOV3Head',
num_classes=1,
in_channels=[512, 256, 128],
out_channels=[1024, 512, 256],
anchor_generator=dict(
type='YOLOAnchorGenerator',
base_sizes=[[(116, 90), (156, 198), (373, 326)],
[(30, 61), (62, 45), (59, 119)],
[(10, 13), (16, 30), (33, 23)]],
strides=[32, 16, 8]),
bbox_coder=dict(type='YOLOBBoxCoder'),
featmap_strides=[32, 16, 8],
loss_cls=dict(
type='CrossEntropyLoss',
use_sigmoid=True,
loss_weight=1.0,
reduction='sum'),
loss_conf=dict(
type='CrossEntropyLoss',
use_sigmoid=True,
loss_weight=1.0,
reduction='sum'),
loss_xy=dict(
type='CrossEntropyLoss',
use_sigmoid=True,
loss_weight=2.0,
reduction='sum'),
loss_wh=dict(type='MSELoss', loss_weight=2.0, reduction='sum')))
# training and testing settings
train_cfg = dict(
assigner=dict(
type='GridAssigner', pos_iou_thr=0.5, neg_iou_thr=0.5, min_pos_iou=0))
test_cfg = dict(
nms_pre=1000,
min_bbox_size=0,
score_thr=0.05,
conf_thr=0.005,
nms=dict(type='nms', iou_threshold=0.45),
max_per_img=100)
# dataset settings
dataset_type = 'VOCDataset'
dataset_root = 'D:/workplace/srtp/handdetection/VOC_HandDataSetVOC2007'
img_norm_cfg = dict(mean=[0, 0, 0], std=[255., 255., 255.], to_rgb=True)
train_pipeline = [
dict(type='LoadImageFromFile', to_float32=True),
dict(type='LoadAnnotations', with_bbox=True),
dict(type='PhotoMetricDistortion'),
dict(
type='Expand',
mean=img_norm_cfg['mean'],
to_rgb=img_norm_cfg['to_rgb'],
ratio_range=(1, 2)),
dict(
type='MinIoURandomCrop',
min_ious=(0.4, 0.5, 0.6, 0.7, 0.8, 0.9),
min_crop_size=0.3),
dict(type='Resize', img_scale=[(320, 320), (608, 608)], keep_ratio=True),
dict(type='RandomFlip', flip_ratio=0.5),
dict(type='Normalize', **img_norm_cfg),
dict(type='Pad', size_divisor=32),
dict(type='DefaultFormatBundle'),
dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels'])
]
test_pipeline = [
dict(type='LoadImageFromFile'),
dict(
type='MultiScaleFlipAug',
img_scale=(608, 608),
flip=False,
transforms=[
dict(type='Resize', keep_ratio=True),
dict(type='RandomFlip'),
dict(type='Normalize', **img_norm_cfg),
dict(type='Pad', size_divisor=32),
dict(type='ImageToTensor', keys=['img']),
dict(type='Collect', keys=['img'])
])
]
data = dict(
samples_per_gpu=1,
workers_per_gpu=1,
train=dict(
type=dataset_type,
ann_file=f'{dataset_root}/ImageSets/Main/hand_train.txt',
img_prefix=f'{dataset_root}',
pipeline=train_pipeline),
val=dict(
type=dataset_type,
ann_file=f'{dataset_root}/ImageSets/Main/hand_val.txt',
img_prefix=f'{dataset_root}',
pipeline=test_pipeline),
test=dict(
type=dataset_type,
ann_file=f'{dataset_root}/ImageSets/Main/hand_test.txt',
img_prefix=f'{dataset_root}',
pipeline=test_pipeline))
# optimizer
optimizer = dict(type='SGD', lr=0.001, momentum=0.9, weight_decay=0.0005)
optimizer_config = dict(grad_clip=dict(max_norm=35, norm_type=2))
# learning policy
lr_config = dict(
policy='step',
warmup='linear',
warmup_iters=2000, # same as burn-in in darknet
warmup_ratio=0.1,
step=[218, 246])
# runtime settings
total_epochs = 273
evaluation = dict(interval=1, metric=['bbox'])

I am trying to make a program in pygame on how to draw a star using a set of points which are variables

1.Question:
I want to learn how to make a star using multiple coordinates as variables and using lines to draw them, what I have done so far is correct but if someone could help me with the other variables and apply them to my code that would be great :D
2 code:
import pygame
from pygame.locals import *
pygame.init
white = (255,255,255)
coordinate2 = 250
coordinate1 = 0
coordinate4 = 500
coordinate3 = 250
screen = pygame.display.set_mode((500,500))
pygame.display.set_caption("AppliedShapes")
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit
exit()
pygame.draw.line(screen,white,(coordinate2,coordinate1),(coordinate4,coordinate3),5)
pygame.display.update()
3 request:
This is what I have so far and it is correct but I want to make more variables and make more lines to make a star. Sooooo if someone could tell me the variables and apply them that would be great!
You can continue like you have, simply defining more coordinateX variables. However, this will eventually become a problem. Imagine having hundreds of separate variables!
A nicer way would be to use a Python list to hold all the co-ordinates:
point_list = [ (250, 0), (500, 250) ]
(There's lots of online tutorials about Python lists.)
Each element can be accessed (or assigned) by using square-bracket notation with an index-number (starting at zero), so point_list[0] is (250, 0); and point_list[1] is (500, 250). To get the individual x,y parts of each co-ordinate, you can add another pair of square brackets, or get all the parts at once:
first_x = points_list[0][0] # 250
first_y = points_list[0][1] # 0
first_x, first_y = points_list[0] # 250, 0
Lists can hold huge amounts of points, for example, a simple 3-point star:
point_list = [ (148, 170), (200, 20), (252, 170), (356, 290), (200, 260), (44, 290) ]
The other nice thing about keeping them in a list is that you can use the PyGame function pygame.draw.polygon() to simply draw them to the screen.
pygame.draw.polygon( window, YELLOW, point_list, 1 )
Or you can "iterate" through the list, drawing the lines:
for i in range( len( points_list ) - 1 ):
pygame.draw.line( screen, white, points_list[i], points_list[i+1], 5 )
Note that I looped with the length-of-list len() minus one, so we didn't go over the end of the list when referencing [i+1].
Here's a quick example I wrote using the above ideas:
Code:
import pygame
# Window size
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 400
DARK_BLUE = ( 3, 5, 54)
STARRY = ( 230, 255, 80 )
### initialisation
pygame.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ) )
pygame.display.set_caption("Star")
# Define a star
centre_coord = ( WINDOW_WIDTH//2, WINDOW_HEIGHT//2 )
star_points = [ (165, 151), (200, 20), (235, 151), (371, 144), (257, 219),
(306, 346), (200, 260), (94, 346), (143, 219), (29, 144) ]
### Main Loop
clock = pygame.time.Clock()
done = False
while not done:
# Handle user-input
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
# Re-draw the window
window.fill( DARK_BLUE ) # background fill
pygame.draw.polygon( window, STARRY, star_points ) # Draw the star
pygame.display.flip() # Update the display
# Clamp FPS
clock.tick_busy_loop(60)
pygame.quit()
Or perhaps a 16-point star of 32 co-ordinates:
point_list = [ (173, 63), (200, 20), (227, 63), (269, 34), (278, 84),
(327, 73), (316, 122), (366, 131), (337, 173), (380, 200),
(337, 227), (366, 269), (316, 278), (327, 327), (278, 316),
(269, 366), (227, 337), (200, 380), (173, 337), (131, 366),
(122, 316), (73, 327), (84, 278), (34, 269), (63, 227),
(20, 200), (63, 173), (34, 131), (84, 122), (73, 73),
(122, 84), (131, 34) ]

How to prevent the initial pytorch variable from changing using a function?

I want to apply a function to the variable x and saved as y. But why the x is also changed? How to prevent it?
import torch
def minus_min(raw):
for col_i in range(len(raw[0])):
new=raw
new[:,col_i] = (raw[:,col_i] - raw[:,col_i].min())
return new
x=torch.tensor([[0,1,2,3,4],
[2,3,4,0,8],
[0,1,2,3,4]])
y=minus_min(x)
print(y)
print(x)
output:
tensor([[0, 0, 0, 3, 0],
[2, 2, 2, 0, 4],
[0, 0, 0, 3, 0]])
tensor([[0, 0, 0, 3, 0],
[2, 2, 2, 0, 4],
[0, 0, 0, 3, 0]])
Because this assignment:
new[:,col_i] = (raw[:,col_i] - raw[:,col_i].min())
is an in-place operation. Therefore, x and y will share the underlying .data.
The smallest change that would solve this issue would be to make a copy of x inside the function:
def minus_min(raw):
new = raw.clone() # <--- here
for col_i in range(len(raw[0])):
new[:,col_i] = raw[:,col_i] - raw[:,col_i].min()
return new
If you want, you can simplify your function (and remove the for loop):
y = x - x.min(dim=0).values

Collision detection in Python(pygame)

I have been wondering how collision detection works, I have had many attempts, but can't get it to work. I am new to pygame, so if anyone is kind enough to read this, please can you add the correct lines to my code as well as explaining it. If anyone was wondering what this code did, it has 2 racecars thatare trying to hit a football and move it in the direction the car is hitting it at(I was thinking a possible way to complete this was to check the angle the car is rotated at, and move the ball by that amount, - 180 degrees to move it forward)
Thank you very much
import pygame
from pygame.math import Vector2
pygame.init()
screen = pygame.display.set_mode((1150, 800))
clock = pygame.time.Clock()
BLUECAR_ORIGINAL = pygame.Surface((100, 30), pygame.SRCALPHA)
pygame.draw.polygon(
BLUECAR_ORIGINAL, (0, 0, 255), [(0, 0), (50, 10), (50, 20), (0, 30)])
bluecar = BLUECAR_ORIGINAL
REDCAR_ORIGINAL = pygame.Surface((50, 30), pygame.SRCALPHA)
pygame.draw.polygon(
REDCAR_ORIGINAL, (200, 0, 0), [(0, 0), (50, 10), (50, 20), (0, 30)])
redcar = REDCAR_ORIGINAL
ball = pygame.draw.circle(screen, [255,255,255],[60,60],5)
pos = Vector2(70, 70)
vel = Vector2(7, 0)
poss = Vector2(70,70)
vell = Vector2(7,0)
redrect = redcar.get_rect(center=pos)
redangle = 0
bluerect = bluecar.get_rect(center=pos)
blueangle = 0
run = True
while run:
ball = pygame.draw.circle(screen, [0,0,0],[575,400],30)
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
redangle += 5
vel.rotate_ip(-5)
redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
redrect = redcar.get_rect(center=pos)
elif keys[pygame.K_RIGHT]:
redangle -= 5
vel.rotate_ip(5)
redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
redrect = redcar.get_rect(center=pos)
if keys[pygame.K_a]:
blueangle += 5
vell.rotate_ip(-5)
bluecar = pygame.transform.rotate(BLUECAR_ORIGINAL, blueangle)
bluerect = bluecar.get_rect(center=pos)
elif keys[pygame.K_d]:
blueangle -= 5
vell.rotate_ip(5)
bluecar = pygame.transform.rotate(BLUECAR_ORIGINAL, blueangle)
bluerect = bluecar.get_rect(center=poss)
hits = pygame.sprites.groupcollide(bluecar, ball, False, False)
hits = pygame.sprites.spritecollide(bluecar, ball, False)
pos += vel
redrect.center = pos
poss += vell
bluerect.center = poss
bgImg = pygame.image.load("Football_pitch.png")
screen.blit(bgImg, (0,0))
screen.blit(redcar, redrect)
screen.blit(bluecar, bluerect)
pygame.display.flip()
clock.tick(60)
pygame.quit()
There are multiple ways:
you could save the coordinates of each sprite as variables and then compare the coordinates of both sprites to each other than do whatever you need to when they are close enough, for example:
if object1_X <= object2_X+5 and object1_X>= object2_X-5 and object1_Y<= object2_Y+5 and object1_Y>=object2_X-5:
#do something
#all that above basically is just saying if the objects above are within a 10-pixel radius of each other do something
pass
or you could use the distance formula:
distance=((object2_X-object1_X)**2+(object2_Y-object1_Y)**2)**0.5
if distance <= 10:
#do something
pass
which utilises the Pythagorean theorem to find the distance between two objects
or you could use pygame's existing function:
object1=pygame.draw.rect(screen,color,[x,y1,50,30],0)
object2=pygame.draw.rect(screen,colorb,[x2,y2,7,7],0)
if object1.colliderect(object2):
#do something
pass
if you were wondering how it works, I am not 100% sure but it likely uses one of the two rudimentary methods internally to calculate this