I am looking to create a repetitive pattern from a single shape (in the example below, the starting shape would be the smallest centre star) using Python. The pattern would look something like this:
To give context, I am working on a project that uses a camera to detect a shape on a rectangle of sand. The idea is that the ripple pattern is drawn out around the object using a pen plotter-type mechanism in the sand to create a zen garden-type feature.
Currently, I am running the Canny edge detection algorithm to create a png (in this example it would be the smallest star). I am able to convert this into an SVG using potrace, but am not sure how to create the ripple pattern (and at what stage, i.e. before converting to an SVG, or after).
Any help would be appreciated!
Here's how I did it:
In the end, I ran a vertex detection algorithm to calculate the shape's vertices.
Then, I sorted them in a clockwise order around the centroid coordinate. Using the svgwrite library, I recreated the shapes using lines.
I 'drew' a circle with a set radius around each vertex and calculated the intersection between the circle and a straight line from the centroid through the vertex.
This gave me two potential solutions (a +ve and a -ve). I chose the point furthest away from the centroid, iterated this method for each vertex and joined the points to create an outline of the shape.
Assing you are using turtle (very beginner friendly) you can use this:
import turtle, math
turtle.title("Stars!")
t = turtle.Turtle()
t.speed(900) # make it go fast
t.hideturtle() # hide turtle
t.width(1.5) # make lines nice & thick
def drawstar(size):
t.up() # make turtle not draw while repositioning
t.goto(0, size * math.sin(144)) # center star at 0, 0
t.setheading(216); # make star flat
t.down() # make turtle draw
for i in range(5): # draw 5 spikes
t.forward(size)
t.right(144)
t.forward(size)
t.right(288)
drawstar(250)
drawstar(200)
drawstar(150)
drawstar(100)
input() # stop turtle from exiting
which creates this:
Related
I am using gluLookAt with a camera whose coordinates are xCam, yCam and zCam. The coordinates of the object the camera is looking at are xPos, yPos, and zPos. There are variables named mouseturnX and mouseturnY, which measure the deviation of the mouse from the middle of the screen in the x-axis and the y-axis. The variable camdist describes the distance between camera and the object it looks at.
The code of the cameraposition is this:
xCam = sin(mouseturnX)*camdist+xPos
yCam = mouseturnY+yPos
zCam = cos(mouseturnX)*camdist+zPos
I now made a polygon object, which I rotate with:
glRotatef(mouseturnX,0,1,0)
Usually it should only show me the backside of the object, it does not matter which position the camera has. But now it does not turn correctly. I tried it with other rotation-axises, there it works fine, but with the y-axis it just does not want to work. I tried changing the camdist from positive to negative, the mouseturnX in the glRotatef function from positive to negative and back to positive again. It just does not work. I used glPushMatrix before the rotation command and glPopMatrix after it. One line before the rotation command I used the translate function to set a fixpoint for the polygon.
Edit: The polygon actually spins, but not in the right amount. It seems like I have to multiply the rotation of the polygon with something.
I found the multiplicator by trying. It is 56.5. It is not perfect, but it works.
I'm currently making a game in pygame, Python 3 and a part of the code that has been giving me issues is:
for counter in range(0, 30):
particles = pygame.image.load('particles.png').convert()
particles = pygame.transform.rotozoom(particles, 36*counter, 1.1**counter).convert()
particles.set_colorkey((0, 0, 0, 0))
screen.blit(particles, particles.get_rect(centerx=480, centery=100))
pygame.display.flip()
time.sleep(0.05)
particles.png is just a few colored pixels on a transparent background. The problem is that when the image is rotated and scaled, some of those particles sort of blur out resulting in a mass of black squares around them.
How do I fix this problem? Thanks in advance!!
I've had a bad experience with pygame's rotozoom combined with transparency. Instead of loading the image and then rotozooming it, consider the following:
Using PIL library:
Convert the loaded surface to a string using pygame.image.tostring
Convert the string to an Image object
Use PIL's functions to replace rotozoom (zooming, rotating)
Convert the Image object back into a surface using the same method
Using math:
Load data about the position and color of the particles,
or infer it from the loaded surface
Use simple mathematical functions to caculate their new position,
according to the angle and zoom
Paint them using pygame.gfxdraw, pygame.draw or pygame.Surface.set_at
Good luck!
I'm trying to rotate of sprite for my game written in pygame
I don't get any consol error, but my sprite stay exactly the same and doesn't rotate :(
Any idea ?
perso.image = pygame.image.load("sprites/[shadow]main_char_sprite.png").convert_alpha()
perso.image = pygame.transform.scale(perso.image, (53,60))
perso.rect = perso.image.get_rect()
perso.rect.x = 200
perso.rect.y = 200
perso.add(perso_group)
while 1:
screen.fill(white)
pygame.transform.rotate(perso.image,30) ########not working :(
all_group.add(statique_group, zombie_group, perso_group)
all_group.draw(screen)
pygame.display.flip()
The documentation for the transform functions says:
All these functions take a Surface to operate on and return a new Surface with the results.
So you need to assign the return value of rotate to the variable:
perso.image = pygame.transform.rotate(perso.image,30)
However, the documentation also says:
Some of the transforms are considered destructive. These means every time they are performed they lose pixel data. Common examples of this are resizing and rotating. For this reason, it is better to retransform the original surface than to keep transforming an image multiple times.
So you may want to keep the original, and keep increasing the rotation angle instead.
I am trying to make a program that gets Pen coordinate from wacom tablet which I manage to figure out using this:
data = display.Display().screen().root.query_pointer()._data
X = data["root_x"]-cfg['winpos'][0]-(cfg['width']/2)
Y = cfg['height']-(data["root_y"]-cfg['winpos'][1])-(cfg['height']/2)
print "Pen Position is: ", X, Y
but problem is that Psychopy has origin coordinate for screen at the centre please refer to pic:
and i am using a wacom INTUOS PTZ1230 12" 12" tablet which i want (0, 0) to start from regular monitor origin from top refer to second pic.
very long to read but all i need is to change my coordinate system in python using psychopy. thanks any bit helps
Experimenters generally present their stimuli symetrically around the center of the screen so, although top left and bottom left are (both) more conventional for the origin, the center of the screen makes most sense for scientists.
The window does have atributes viewScale and viewPos though. Although they aren't designed quite for this purpose I think you could use viewPos to shift the origin.
Jon
I'm trying to do what the title says. I have a character with a gun constrained to its hand, and I'm trying to get the gun to point at the cursor. I figured that a DampedRotarySpring would be a nice way to do it, but it turns out not to be as simple as that. The gun is a dynamic body with a Segment shape, and for the cursor I create a static body whose position I set to the mouse location with pygame each step.
When I run the program, the gun simply does not move at all except for the effect of gravity or collisions.
Here is the relevant code:
# add crosshairs at the location of the mouse
pointer_body = pymunk.Body()
pointer_shape1 = pymunk.Segment(pointer_body, (0,CROSSHAIRS_SIZE), (0,-CROSSHAIRS_SIZE), 1) # vertical segment
pointer_shape2 = pymunk.Segment(pointer_body, (-CROSSHAIRS_SIZE,0), (CROSSHAIRS_SIZE,0), 1) # horizontal segment
# add a spring that will angle the gun toward the mouse
spring = pymunk.DampedRotarySpring(me.gun.body, pointer_body, 0, 0.01, 1)
space.add(pointer_shape1, pointer_shape2, spring)
while True:
# handle event queue
for event in pygame.event.get():
if event.type == pygame.MOUSEMOTION:
from math import atan2
# update location of pointer
pointer_body.position = flipy(pygame.mouse.get_pos())
pointer_body.angle = atan2( (pointer_body.position.y - me.gun.body.position.y), (pointer_body.position.x - me.gun.body.position.x) )
Edit:
Here is a Gist repository of all my code: https://gist.github.com/4470807.
The main loop is in ragdoll.py.
The problem with the code in the gist is that you have attached the gun to the hand with two joints to keep them in the same place and same rotation. However, the the hand is a rouge body and wont rotate. Therefor the gun wont rotate when its pulled by the spring between it and the cursor, because that other joint is stronger.
Im not sure exactly how you want the setup, but you can see that it all works if you remove the RotaryLimitJoint from the gun-hand.
Take a look at a fixed fork of the code for the exact details: https://gist.github.com/4505219
Some tips for future troubleshooting that I did to find the problem:
Make everything 10x bigger so its easy to see what happens. I know pymunk only draws in one size, but it was easy to just add a 0 on the end of all sizes in the code.
Make the hand not move so its easier to see how it rotates (removed all stuff in the update_hand_position method)
Disable collisions between all shapes in the scene so that the rotating gun is not hindered by some body part. (did a simple loop of space.shapes and ran shape.group=1)
Maybe your problem is with the spring parameters? The stiffness and damping looks very low unless the gun is extremely light.
Check out this code example I added to pymunk yesterday: http://code.google.com/p/pymunk/source/browse/trunk/examples/damped_rotary_spring_pointer.py
(There is one thing going on with the rotation when it flip over between positive and negative pi that I will look at)