Skip to content

Latest commit

 

History

History
294 lines (221 loc) · 7.08 KB

File metadata and controls

294 lines (221 loc) · 7.08 KB
Error in user YAML: (<unknown>): did not find expected key while parsing a block mapping at line 1 column 1
---
show: step
version: 1.0 
enable_checker: true
- 本教程同步发布在: 
	- 个人网站: `https://oeasy.org` 
	- 蓝桥云课: `https://www.lanqiao.cn/courses/3584` 
	- GitHub: `https://github.com/overmind1980/oeasy-python-tutorial` 
	- Gitee: `https://gitee.com/overmind1980/oeasypython` 
---

  • oeasy Python 0685
  • 这是 oeasy 系统化 Python 教程,从基础一步步讲,扎实、完整、不跳步。愿意花时间学,就能真正学会。

rotation_旋转_角度值_弧度制转化

开始

  • 配套视频
  • 上次我们研究了
    • 物体的旋转
    • 有三个轴向
英文 中文 作用
heading 航向轴 转头
pitch 俯仰轴 点头
bank 横滚 歪头 盗梦空间特效

图片描述

  • 可以 再用猴头理解 三轴旋转吗?🤔

构建环境

  • 修改代码
import bpy
bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
for num in range(13):
    bpy.ops.mesh.primitive_monkey_add(size = 1)
    bpy.context.object.location = (0,num,0)
  • 然后进入blender中
    • 在文本调板中
    • Relaod
    • Run

图片描述

  • 得到一排猴子
  • 想让猴子低头30度?

俯仰轴

  • 猴子在 红轴方向上
    • 旋转30度
      • = 30 / 360 * π * 2
      • = π / 6
      • ≈ 3.14 / 6
    • 低头
bpy.context.object.rotation_euler[0] = 3.14 / 6
  • 调整旋转中的第0个分量
    • rotation_euler[0] = 3.14 / 6

图片描述

  • 0号旋转轴 为
    • 俯仰轴
    • pitch
    • 负责 低头抬头
  • 现在全都低头认错...

横滚轴

  • 我要他们抬起头来
bpy.context.object.rotation_euler[0] = - 3.14 / 6
  • 全都仰望星空了

图片描述

  • y轴是什么方向呢?

y轴

bpy.context.object.rotation_euler[1] = 3.14 / 6
  • 猴子在绿轴方向上 旋转 60度
    • 歪头 60度

图片描述

  • 1号旋转轴 为
    • 横滚轴
    • bank
    • 负责 歪头

航向轴

bpy.context.object.rotation_euler[2] = 3.14 / 6
  • 猴子 在垂直于红绿轴平面的 z轴上旋转 60度
    • 转头 60度

图片描述

  • 2号坐标轴 为

    • 航向轴
    • heading
    • 负责转头
  • 来一面 猴子墙

基础墙面

import bpy

bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
for x in range(10):
    for z in range(10):
        bpy.ops.mesh.primitive_monkey_add(size=1)
        bpy.context.object.location=(x,0,z)
  • 效果

图片描述

  • 加点随机效果

随机转动

  • 横滚轴上 循转一个随机数
import bpy
import random

bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
for x in range(10):
    for z in range(10):
        r = random.random()
        bpy.ops.mesh.primitive_monkey_add(size=1)
        bpy.context.object.location=(x,0,z)
        bpy.context.object.rotation_euler[1] = r
  • 方向单一

图片描述

  • 尝试修改

修改角度

import bpy
import random

bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
for x in range(10):
    for z in range(10):
        r = random.random()
        bpy.ops.mesh.primitive_monkey_add(size=1)
        bpy.context.object.location=(x,0,z)
        bpy.context.object.rotation_euler[1] = r-0.5
  • 效果

图片描述

  • 这有什么意义吗?

随机的意义

图片描述

  • 树冠的形态

图片描述

# -*- coding: utf-8 -*-
# 诗句: 枫红映水晚江秋 (材质创建修正版)

import bpy
import math
import random

def clear_scene():
    if bpy.context.object and bpy.context.object.mode == 'EDIT':
        bpy.ops.object.mode_set(mode='OBJECT')
    bpy.ops.object.select_all(action='SELECT')
    bpy.ops.object.delete()
    for block in bpy.data.meshes:
        if block.users == 0: bpy.data.meshes.remove(block)
    for block in bpy.data.materials:
        if block.users == 0: bpy.data.materials.remove(block)

def create_principled_material(name, color):
    mat = bpy.data.materials.new(name=name)
    mat.use_nodes = True
    nodes = mat.node_tree.nodes; nodes.clear()
    output_node = nodes.new(type='ShaderNodeOutputMaterial')
    bsdf_node = nodes.new(type='ShaderNodeBsdfPrincipled')
    bsdf_node.inputs['Base Color'].default_value = color
    mat.node_tree.links.new(bsdf_node.outputs['BSDF'], output_node.inputs['Surface'])
    return mat

# --- 1. 清理并设置场景 ---
clear_scene()
scene = bpy.context.scene
scene.render.engine = 'CYCLES'
scene.cycles.device = 'GPU'
scene.cycles.samples = 256
scene.render.fps = 30
scene.frame_start = 1
scene.frame_end = 4 * scene.render.fps
scene.render.filepath = f"//render/poem_01/frame_"

# --- 2. 创建环境和灯光 ---
world = scene.world
bpy.ops.object.light_add(type='SUN', location=(0, 0, 30))
sun = bpy.context.object
sun.data.energy = 2.0
sun.rotation_euler = (math.radians(30), math.radians(-30), 0)

# 创建程序化的枫树
maple_mat = create_principled_material("MapleLeafMaterial", (0.8, 0.1, 0.05, 1.0))
for i in range(5):
    x, y = -15 + i * 6 + random.uniform(-1,1), random.uniform(8, 12)
    bpy.ops.mesh.primitive_cylinder_add(radius=0.2, depth=4, location=(x, y, 2))
    for j in range(50):
        rand_x = x + random.uniform(-1.5, 1.5)
        rand_y = y + random.uniform(-1.5, 1.5)
        rand_z = 4 + random.uniform(-1.0, 1.5)
        bpy.ops.mesh.primitive_ico_sphere_add(radius=random.uniform(0.3, 0.5), location=(rand_x, rand_y, rand_z))
        leaf = bpy.context.object
        leaf.data.materials.append(maple_mat)

# --- 4. 设置和动画化摄像机 ---
bpy.ops.object.empty_add(type='SPHERE', location=(0, 0, 3))
pivot = bpy.context.object; pivot.name = "CameraPivot"
bpy.ops.object.camera_add(location=(0, -20, 0), rotation=(math.radians(85), 0, 0))
camera = bpy.context.object; camera.parent = pivot
scene.camera = camera

pivot.location = (-10, -5, 4)
pivot.keyframe_insert(data_path="location", frame=scene.frame_start)
pivot.location = (10, -5, 4)
pivot.keyframe_insert(data_path="location", frame=scene.frame_end)

总结 🤔

  • 这次 研究了 旋转函数

    • rotation_euler 旋转
  • xyz 三个轴向的旋转值构成一个列表

    • rotation_euler[0] 是 x
    • rotation_euler[1] 是 y
    • rotation_euler[2] 是 z
  • 可以让飞机排成一个阵列吗?

  • 应该如何做呢?🤔

  • 我们下次再说!👋

  • 配套视频


  • 本文来自 oeasy Python 系统教程。
  • 想完整、扎实学 Python,
  • 搜索 oeasy 即可。