1. Introduction
Stick Figure (matchmaker) is a minimalist style of graphics, usually consisting of simple lines and circles, yet vividly expresses the posture and movement of the character. Tinder is not only widely used in animation, comics and doodles, but also as a teaching and research tool in the fields of graphics and artificial intelligence. The purpose of this article is to introduce how to use Python to realize the design and drawing of Matchmaker, and to let readers understand the basic principle behind Matchmaker and the implementation method through programming.
2. Preparation
Before you start implementing Tinder, you need to make sure that you have installed the Python environment and are familiar with basic Python programming. In addition, to draw graphics, we will use thematplotlib
Library, a powerful plotting library for generating a wide variety of static, dynamic and interactive diagrams.
You can install it with the following commandmatplotlib
:
bash copy code
pip install matplotlib
3. Basic theoretical knowledge
The drawing of Matchmaker relies heavily on geometric drawing and transformations. Specifically, we need:
(1)Defining the joints: Matchmaker's joints include the head, shoulders, elbows, wrists, hips, knees and ankles. These joints can be thought of as points in two or three dimensions.
(2)Drawing Line Segments: Depending on the location of the joints, draw the line segments connecting the joints, which form the bones of the matchmaker.
(3)Add Circle: Add circles to represent joints such as the head.
(4)Transformations and animations: By changing the position of the joints, you can realize the movement and animation effects of the matches.
4. Step-by-step details
Below, we present a step-by-step guide on how to use Python and thematplotlib
Draw Matchmaker.
(1)import library
First, we need to import thematplotlib
librarypyplot
Module:
import as plt
import numpy as np
(2)Defining joint positions
For simplicity, let's start by defining the joint positions of a matchmaker on a two-dimensional plane. Here is an example of a simple matchmaker standing position:
# Defining joint positions
head = [0, 1]
torso = [0, 0]
left_shoulder = [-0.5, 0]
left_elbow = [-1, -0.5]
left_hand = [-1, -1]
right_shoulder = [0.5, 0]
right_elbow = [1, -0.5]
right_hand = [1, -1]
left_hip = [-0.5, -0.5]
left_knee = [-1, -1.5]
left_foot = [-1, -2]
right_hip = [0.5, -0.5]
right_knee = [1, -1.5]
right_foot = [1, -2]
# Storing joint positions in a dictionary
joints = {
'head': head,
'torso': torso,
'left_shoulder': left_shoulder,
'left_elbow': left_elbow,
'left_hand': left_hand,
'right_shoulder': right_shoulder,
'right_elbow': right_elbow,
'right_hand': right_hand,
'left_hip': left_hip,
'left_knee': left_knee,
'left_foot': left_foot,
'right_hip': right_hip,
'right_knee': right_knee,
'right_foot': right_foot
}
(3)Drawing Matchmaker
Next, we write a function that draws matches based on joint positions:
def draw_stick_figure(joints, ax):
# Drawing the body
body_parts = [
('torso', 'head'),
('torso', 'left_shoulder'), ('left_shoulder', 'left_elbow'), ('left_elbow', 'left_hand'),
('torso', 'right_shoulder'), ('right_shoulder', 'right_elbow'), ('right_elbow', 'right_hand'),
('torso', 'left_hip'), ('left_hip', 'left_knee'), ('left_knee', 'left_foot'),
('torso', 'right_hip'), ('right_hip', 'right_knee'), ('right_knee', 'right_foot')
]
for start, end in body_parts:
start_pos = (joints[start])
end_pos = (joints[end])
([start_pos[0], end_pos[0]], [start_pos[1], end_pos[1]], 'k-')
# Drawing the head
circle = (joints['head'], 0.1, color='black', fill=True)
ax.add_patch(circle)
# Drawing hands(selectable)
circle = (joints['left_hand'], 0.05, color='black', fill=True)
ax.add_patch(circle)
circle = (joints['right_hand'], 0.05, color='black', fill=True)
ax.add_patch(circle)
# Drawing Feet(selectable)
circle = (joints['left_foot'], 0.05, color='black', fill=True)
ax.add_patch(circle)
circle = (joints['right_foot'], 0.05, color='black', fill=True)
ax.add_patch(circle)
(4)Drawing and displaying graphics
Finally, we create a graphical object, call the draw function, and display the result:
def main():
fig, ax = ()
ax.set_aspect('equal')
('off') # Close Axis
draw_stick_figure(joints, ax)
()
if __name__ == "__main__":
main()
5. Frequently Asked Questions
(1)Tinder looks distorted or out of proportion: This is usually caused by poorly defined joint positions or incorrectly connected line segments. Check that the joint positions and connection order are correct.
(2)Incomplete graphic display: Ensure that the settingsax.set_aspect('equal')
, so that the graph is displayed in equal proportions.
(3)How to add animation effects: can be usedmatplotlib
(used form a nominal expression)FuncAnimation
class, which animates the joints by constantly updating their positions.
6. Results case sharing
With the above steps, you have successfully drawn a simple matchmaker. Next, we can try more complex poses and animation effects. For example, by changing the position of the joints, we can realize the movement of the matchmaker such as jumping and walking.
Below is a simple animation example showing a matchmaker moving from left to right:
import as animation
def update_position(frame, joints):
# Here we simply move the matchmaker to the right
translation = 0.1 * frame
for key in ():
joints[key][0] += translation
return joints
def animate(frame):
global joints_anim
joints_anim = update_position(frame, joints_anim)
()
ax.set_aspect('equal')
('off')
draw_stick_figure(joints_anim, ax)
def main_animation():
fig, ax = ()
global joints_anim
joints_anim = {key: () for key, value in ()} # Copy the initial joint position
ani = (fig, animate, frames=100, interval=100)
()
if __name__ == "__main__":
main_animation()
7. Case code example
Below is the complete code example with all steps and comments:
import as plt
import as numpy as np
import as animation
# Define joint positions
joints = {
'left_shoulder': [-0.5, 0],
'left_elbow': [-1, -0.5],
'right_shoulder': [0.5, 0],
'right_elbow': [1, -0.5],
'left_hip': [-0.5, -0.5],
'left_foot': [-1, -2],
'right_knee': [1, -1.5],
'right_foot': [1, -2]
}
# Convert the joint positions into a numpy array for math operations
joints = {key: (value) for key, value in ()}
# The function that draws the matchmaker
def draw_stick_figure(joints, ax).
# Clear the previous drawing
()
# Set the scale and limits of the axes
ax.set_aspect('equal')
ax.set_xlim(-2, 2)
ax.set_ylim(-2.5, 1.5)
# Define body parts and corresponding colors (optional)
body_parts = [
('torso', 'head', 'black'),
('torso', 'right_shoulder', 'black'), ('right_shoulder', 'right_elbow', 'black'), ('right_elbow', 'right_hand', 'black'), ('left_elbow', 'left_hand', 'black'), ('left_elbow', 'left_hand', 'black'), ('left_elbow', 'left_elbow', 'left_hand', 'black')
('torso', 'right_hip', 'black'), ('right_hip', 'right_knee', 'black'), ('right_knee', 'right_foot', 'black')
]
# Draw the parts of the matchmaker
for part in body_parts.
start_joint, end_joint, color = part[0], part[1], part[2] if len(part) > 2 else 'black'
([joints[start_joint][0], joints[end_joint][0]], [joints[start_joint][1], joints[end_joint][1]], color=color, linewidth=2)
# Show grid (optional)
(True)
# Create the figure and axes
fig, ax = ()
# Initialization function (for animation)
def init(): # draw_stick_figure(joints, ax)
draw_stick_figure(joints, ax)
return [] # Returns an empty list, since we don't have an artist object that needs to be updated
# Animation update function
def update(frame).
# Here you can add logic that causes the matchmaker to move or change its pose
# For example, simply rotating an arm or leg
# But for simplicity, we don't change the joint positions here
draw_stick_figure(joints, ax)
return [] # Also returns the empty list
# Create the animation
ani = (fig, update, frames=100, init_func=init, blit=True, interval=100)
# Display the graphics
()
Please note the following:
(1) I converted the joint positions tonumpy
arrays to do math when needed (though not used in this simple example).
(2) Indraw_stick_figure
function, I added code to set axis scaling and limits, and an optional grid display.
(3) Inbody_parts
In the list, I added the color parameter, but in this example, I used black by default. You can change the color as needed.
(4) Inupdate
In the function, I didn't change the joint positions, so the matchmaker stays stationary in the animation. You can add logic to change the pose or position of the matchmaker as needed.
(5) I usedFuncAnimation
to create the animation, and set 100 frames and an interval of 100 milliseconds between each frame. You can adjust these parameters as needed.
Running this code will display a window containing a static matchmaker, and due to the animation setup, it will redraw it every 100 milliseconds (even though it appears to be static because the joint positions have not changed; interested readers can try changing the joint positions).