news 2026/9/12 20:00:33

Manim数学动画:旋转扭曲特效原理与实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Manim数学动画:旋转扭曲特效原理与实践

1. Manim与数学动画的革命性结合

第一次看到用Manim制作的旋转扭曲特效时,那种将抽象数学概念具象化的震撼感至今难忘。作为一款专为数学可视化设计的Python框架,Manim正在改变我们理解和教授数学的方式。不同于普通的动画工具,Manim允许你通过精确的数学定义来构建动画,这种"用数学描述数学"的范式正是其独特魅力所在。

旋转扭曲特效(Twisting Effect)是Manim中极具表现力的一类动画,它能将平面图形通过旋转变换逐渐扭曲成三维形态,或者让几何体产生螺旋形变。这种效果特别适合演示复变函数中的共形映射、拓扑学中的连续变形,甚至是物理学中的场论概念。我在教授微分几何时,就经常用这种特效来展示曲面的高斯映射过程。

2. 环境搭建与基础准备

2.1 Manim的版本选择与安装

当前Manim社区主要维护两个版本:原版Manim(ManimCairo)和社区版Manim(ManimCE)。对于旋转扭曲特效的开发,我推荐使用ManimCE,因为它有更活跃的社区支持和更完善的3D功能。安装过程非常简单:

pip install manim

注意:建议在Python 3.8+环境中安装,某些依赖项在新版本Python中可能存在问题。如果遇到OpenGL相关错误,可能需要额外安装系统级的图形库。

2.2 基础场景结构解析

每个Manim动画都继承自Scene类,旋转扭曲特效通常需要自定义动画曲线。以下是一个基础模板:

from manim import * class BasicTwist(Scene): def construct(self): # 创建初始图形 square = Square() self.play(Create(square)) # 应用旋转扭曲动画 self.play(square.animate.apply_function( lambda p: [ p[0]*np.cos(p[2]) - p[1]*np.sin(p[2]), p[0]*np.sin(p[2]) + p[1]*np.cos(p[2]), p[2] ] )) self.wait()

这段代码展示了最基本的扭曲变换:在z轴方向逐渐旋转平面图形。apply_function方法允许我们定义任意的点变换函数。

3. 旋转扭曲的核心数学原理

3.1 三维旋转变换矩阵

旋转扭曲特效的本质是应用了随时间变化的空间变换。在三维空间中,绕各坐标轴的旋转矩阵如下:

  • 绕x轴旋转θ角度:

    [1, 0, 0 ] [0, cosθ, -sinθ ] [0, sinθ, cosθ ]
  • 绕y轴旋转θ角度:

    [ cosθ, 0, sinθ ] [ 0, 1, 0 ] [-sinθ, 0, cosθ ]
  • 绕z轴旋转θ角度:

    [cosθ, -sinθ, 0] [sinθ, cosθ, 0] [0, 0, 1]

在Manim中,我们可以组合这些基础变换来创建复杂的扭曲效果。例如,让旋转角度随z坐标变化,就能产生螺旋扭曲。

3.2 参数化曲面与变形技术

更高级的扭曲效果需要参数化曲面技术。考虑一个参数化曲面S(u,v) = (x(u,v), y(u,v), z(u,v)),我们可以定义时间依赖的变形:

def twisted_surface(u, v, t): angle = t * v # 扭曲角度随v参数变化 x = np.cos(angle) * u y = np.sin(angle) * u z = v return np.array([x, y, z])

这种技术可以用来展示莫比乌斯带等拓扑结构。在Manim中,Surface类专门用于处理这类参数化曲面。

4. 进阶扭曲特效实现

4.1 动态纹理扭曲

给扭曲对象添加纹理可以大幅增强视觉效果。Manim的set_color_by_gradient方法可以创建彩虹色渐变:

class TextureTwist(ThreeDScene): def construct(self): self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES) surface = Surface( lambda u, v: np.array([ u * np.cos(v), u * np.sin(v), -0.5 * u ]), u_range=[-2, 2], v_range=[0, 2*PI] ) surface.set_color_by_gradient(BLUE, GREEN, YELLOW, RED) self.play(Create(surface)) self.play(surface.animate.apply_function( lambda p: [ p[0] * (1 + 0.3*np.sin(2*p[2])), p[1] * (1 + 0.3*np.cos(2*p[2])), p[2] ] ), run_time=3)

这个例子创建了一个带有动态扭曲的彩色曲面,扭曲幅度随z坐标周期性变化。

4.2 多对象协同扭曲

复杂场景可能需要多个对象以不同方式扭曲。这时可以使用AnimationGroup来协调多个动画:

class MultiTwist(Scene): def construct(self): circle = Circle(radius=1.5, color=BLUE) square = Square(side_length=2, color=RED) triangle = Triangle(color=GREEN).scale(1.5) group = VGroup(circle, square, triangle) self.play(Create(group)) # 定义不同的扭曲函数 def circle_twist(p): return [p[0]*np.cos(p[1]), p[0]*np.sin(p[1]), 0] def square_twist(p): return [p[0], p[1]*np.cos(p[0]), p[1]*np.sin(p[0])] def triangle_twist(p): return [p[0]*(1+0.5*np.sin(p[1])), p[1]*(1+0.5*np.cos(p[0])), 0] self.play( AnimationGroup( circle.animate.apply_function(circle_twist), square.animate.apply_function(square_twist), triangle.animate.apply_function(triangle_twist), lag_ratio=0.5 ), run_time=4 )

这种技术非常适合展示不同几何体在相同变换规则下的不同表现。

5. 性能优化与渲染技巧

5.1 网格细分与质量平衡

扭曲动画的质量很大程度上取决于几何体的细分程度。Manim的resolution参数控制着曲面的网格密度:

# 高分辨率曲面(渲染慢但质量高) high_res = Surface( lambda u,v: [...], resolution=(50,50) ) # 低分辨率曲面(渲染快但可能有锯齿) low_res = Surface( lambda u,v: [...], resolution=(20,20) )

实战经验:对于4K渲染,resolution=(30,30)通常足够;1080p视频用(20,20)即可。复杂的扭曲动画建议先在低分辨率下测试,最终渲染再提高质量。

5.2 智能缓存与预渲染

长时间动画可以分段渲染后合成。Manim支持从特定帧开始渲染:

manim -ql --from_frame 100 -n 200 my_animation.py MyScene

这个命令从第100帧开始渲染,共渲染200帧。对于复杂的扭曲动画,我通常会:

  1. 先渲染低质量预览版(-ql参数)
  2. 确认动画效果后,分段渲染高质量版本
  3. 使用FFmpeg合并分段视频

6. 数学可视化案例实战

6.1 复变函数可视化

旋转扭曲特效非常适合展示复变函数。例如,函数f(z)=e^z的映射可以这样实现:

class ComplexExponential(Scene): def construct(self): # 创建网格 grid = ComplexPlane() grid.prepare_for_nonlinear_transform() self.play(Create(grid)) # 应用指数函数变换 self.play(grid.animate.apply_complex_function( lambda z: np.exp(z) ), run_time=3) # 添加扭曲动画 self.play(grid.animate.apply_function( lambda p: [ p[0] * np.cos(p[1]/2), p[1] * np.sin(p[0]/2), p[1] * 0.2 ] ), run_time=2)

这个动画生动展示了指数函数如何将直线网格映射为极坐标网格。

6.2 拓扑学中的连续变形

用扭曲动画演示同伦变换:

class HomotopyDemo(Scene): def construct(self): path1 = Circle(radius=2) path2 = Square(side_length=3).rotate(PI/4) self.play(Create(path1)) self.wait() # 同伦变换动画 def homotopy(x, y, z, t): # t=0时为path1,t=1时为path2 return interpolate( path1.point_from_proportion(x), path2.point_from_proportion(x), t ) self.play(Homotopy(homotopy, path1), run_time=3) # 添加扭曲效果 self.play(path1.animate.apply_function( lambda p: [ p[0] * (1 + 0.3*np.sin(PI*p[1])), p[1] * (1 + 0.3*np.cos(PI*p[0])), 0 ] ))

这种可视化能帮助学生直观理解拓扑等价的概念。

7. 常见问题与解决方案

7.1 扭曲后图形撕裂问题

当扭曲幅度过大时,可能会出现网格撕裂。解决方法包括:

  1. 增加resolution参数提高网格密度
  2. 使用更平滑的插值函数,如用np.tanh替代np.sin
  3. 分阶段应用扭曲,每次变形幅度小一些
# 平滑扭曲函数示例 def smooth_twist(p): twist_amount = 0.5 * np.tanh(p[1]) # 使用tanh限制扭曲幅度 return [ p[0] * np.cos(twist_amount), p[0] * np.sin(twist_amount), p[1] ]

7.2 3D场景渲染异常

在3D扭曲动画中可能会遇到:

  • 对象突然消失(裁剪平面问题)
  • 光照异常
  • 深度测试错误

解决方案:

class Fixed3DRender(ThreeDScene): def construct(self): # 调整相机和渲染参数 self.set_camera_orientation( phi=60*DEGREES, theta=-45*DEGREES, distance=10, frame_center=[0,0,1] # 调整中心点避免裁剪 ) self.camera.set_z_index(0) # 解决深度排序问题 # 创建带光照的材质 material = SurfaceMaterial( specular=0.5, roughness=0.1, shadow=0.3 ) # 应用扭曲动画...

7.3 动画卡顿问题

复杂扭曲动画可能渲染缓慢。优化技巧:

  1. 使用-qh参数预览时降低质量
  2. 减少不必要的抗锯齿
  3. 简化物理模拟精度
  4. 使用@override_animation装饰器自定义轻量级动画
from manim.utils.rate_functions import ease_out_sine class OptimizedTwist(Scene): @override_animation(Create) def _optimized_create(self, mobject, **kwargs): # 自定义创建动画,跳过复杂计算 return ApplyMethod( mobject.set_opacity, 1, rate_func=ease_out_sine, **kwargs ) def construct(self): complex_obj = MyComplexObject() # 假设这是个复杂对象 self.play(Create(complex_obj)) # 将使用优化后的动画

8. 创意扩展与高级应用

8.1 结合物理模拟

Manim可以结合物理引擎创建更真实的扭曲效果。虽然Manim本身没有内置物理引擎,但可以集成Pymunk等库:

import pymunk class PhysicsTwist(Scene): def construct(self): # 初始化物理空间 space = pymunk.Space() space.gravity = (0, -900) # 创建物理对象 body = pymunk.Body() shape = pymunk.Circle(body, radius=1) space.add(body, shape) # 同步到Manim对象 circle = Circle(radius=1) self.add(circle) # 模拟帧更新 def update(mob, dt): space.step(dt) mob.move_to([body.position.x, body.position.y, 0]) circle.add_updater(update) # 应用外力产生扭曲 def apply_twist_force(): body.apply_force_at_local_point( (1000, 0), (0, 1) ) self.play( ApplyFunction(apply_twist_force), run_time=2 )

8.2 交互式扭曲控制

虽然Manim主要生成预渲染动画,但可以结合ManimGL或导出到交互式环境:

class InteractiveTwist(Scene): def construct(self): slider = NumberLine(x_range=[0, 2*PI]) knob = Dot().move_to(slider.n2p(0)) def update_twist(mob): angle = slider.p2n(knob.get_center()) mob.become( Square().apply_function( lambda p: [ p[0]*np.cos(angle*p[1]), p[0]*np.sin(angle*p[1]), 0 ] ) ) square = Square() square.add_updater(update_twist) self.add(slider, knob, square) self.play( knob.animate.move_to(slider.n2p(PI)), run_time=3 )

这种技术适合创建教学演示,让学生通过参数调整观察扭曲效果变化。

9. 项目实战:创建莫比乌斯带动画

让我们综合运用所学技术,创建一个完整的莫比乌斯带动画:

class MobiusBand(ThreeDScene): def construct(self): self.set_camera_orientation(phi=75*DEGREES, theta=30*DEGREES) # 参数化莫比乌斯带 def mobius_param(u, v): u = u * TAU # 0~1映射到0~2π v = v * 2 - 1 # 0~1映射到-1~1 return np.array([ (1 + v/2 * np.cos(u/2)) * np.cos(u), (1 + v/2 * np.cos(u/2)) * np.sin(u), v/2 * np.sin(u/2) ]) mobius = Surface( mobius_param, resolution=(32, 16), u_range=[0, 1], v_range=[0, 1] ) mobius.set_color_by_gradient(RED, BLUE) # 创建切割动画 cut_plane = Square(side_length=3, fill_opacity=0.3, stroke_width=0) cut_plane.rotate(PI/2, RIGHT) cut_plane.set_color(YELLOW) self.play(Create(mobius), run_time=2) self.play(cut_plane.animate.move_to(2*RIGHT), run_time=1.5) # 展示单面特性 self.play( mobius.animate.apply_function( lambda p: [ p[0] * (1 + 0.2*np.sin(p[2]*3)), p[1] * (1 + 0.2*np.cos(p[2]*3)), p[2] ] ), run_time=3 ) # 展开为长方形 self.play( mobius.animate.apply_function( lambda p: [ p[0] * 0.5, p[1] * 0.5, p[2] * 0.2 ] ), run_time=2 ) # 添加扭曲动画展示形成过程 def twist_formation(p, alpha): # alpha从0到1表示动画进度 u = p[0] * 0.5 v = p[1] * 0.5 twist = alpha * PI return np.array([ (1 + v * np.cos(u + twist)) * np.cos(u), (1 + v * np.cos(u + twist)) * np.sin(u), v * np.sin(u + twist) ]) self.play( UpdateFromAlphaFunc( mobius, lambda mob, alpha: mob.become( Surface( lambda u,v: twist_formation([u,v,0], alpha), resolution=(32,16) ).set_color_by_gradient(RED, BLUE) ), run_time=4 ) )

这个动画完整展示了莫比乌斯带的形成过程,结合了参数化曲面、动态扭曲和变形动画等多种技术。

10. 渲染输出与后期处理

10.1 高质量渲染设置

对于最终成品视频,推荐使用这些参数:

manim -p -qh --format=mp4 --renderer=opengl my_animation.py MyScene

关键参数说明:

  • -p: 预览渲染结果
  • -qh: 高质量(1080p)
  • --format=mp4: 输出MP4格式
  • --renderer=opengl: 使用GPU加速的OpenGL渲染器

对于4K输出:

manim -p -qk --format=mp4 --resolution=3840,2160 my_animation.py MyScene

10.2 视频后期处理技巧

虽然Manim可以直接输出视频,但有时需要额外处理:

  1. 色彩校正:Manim的颜色可能在导出后变淡,可以用FFmpeg增强:
ffmpeg -i input.mp4 -vf "eq=contrast=1.1:brightness=0.02:saturation=1.2" output.mp4
  1. 添加音频:数学动画配上合适的音乐更能吸引观众:
ffmpeg -i video.mp4 -i audio.mp3 -c:v copy -c:a aac -map 0:v:0 -map 1:a:0 final.mp4
  1. 多场景合并:将多个场景渲染为独立视频后合并:
ffmpeg -f concat -i file_list.txt -c copy final_animation.mp4

其中file_list.txt内容格式为:

file 'scene1.mp4' file 'scene2.mp4'

11. 教学应用与知识可视化

旋转扭曲特效在数学教育中有着广泛的应用场景:

11.1 线性代数教学

演示矩阵变换的几何意义时,扭曲动画能让抽象概念具象化。比如展示特征向量如何保持方向:

class EigenDemo(Scene): def construct(self): # 创建网格 grid = NumberPlane() self.play(Create(grid)) # 定义变换矩阵 transform_matrix = np.array([ [1.5, 0.5], [0.5, 1.0] ]) # 应用线性变换 self.play(grid.animate.apply_matrix(transform_matrix)) # 添加扭曲动画展示非线性变换对比 self.play(grid.animate.apply_function( lambda p: [ p[0] + 0.3*p[1]*np.sin(p[0]), p[1] + 0.3*p[0]*np.cos(p[1]), 0 ] ))

这种对比能帮助学生理解线性变换的特殊性。

11.2 微分几何应用

展示曲面曲率时,扭曲动画可以可视化高斯映射:

class GaussianMap(ThreeDScene): def construct(self): self.set_camera_orientation(phi=75*DEGREES, theta=30*DEGREES) # 创建曲面 surface = Surface( lambda u,v: np.array([ u, v, np.sin(u)*np.cos(v) ]), u_range=[-3,3], v_range=[-3,3], resolution=(24,24) ) surface.set_color_by_gradient(GREEN, BLUE) # 创建法向量场 normals = VGroup() for u in np.linspace(-2.5, 2.5, 6): for v in np.linspace(-2.5, 2.5, 6): point = surface.u_v_to_point(u,v) normal = self.get_normal_vector(surface, u, v) arrow = Arrow( start=point, end=point+normal*0.5, color=RED, buff=0 ) normals.add(arrow) self.play(Create(surface), run_time=2) self.play(Create(normals), run_time=2) # 高斯映射动画:将法向量归一化并映射到单位球 def gauss_map(p, alpha): if p[2] > 0: # 只处理法向量 return p * alpha + normalize(p) * (1-alpha) return p self.play( UpdateFromAlphaFunc( normals, lambda mob, alpha: mob.become( VGroup(*[ Arrow( start=arrow.get_start(), end=gauss_map(arrow.get_end()-arrow.get_start(), alpha) + arrow.get_start(), color=arrow.get_color(), buff=0 ) for arrow in mob ]) ), run_time=3 ) ) # 添加曲面扭曲展示曲率变化 self.play(surface.animate.apply_function( lambda p: [ p[0], p[1], np.sin(p[0]*0.7)*np.cos(p[1]*0.7) ] ), run_time=2)

这种动画能直观展示曲面不同区域的曲率变化。

12. 社区资源与进阶学习

12.1 优质学习资源推荐

  1. 官方文档

    • Manim Community版文档
    • 特别关注"Advanced Techniques"和"3D Rendering"章节
  2. 开源项目参考

    • Manim示例库:https://github.com/ManimCommunity/example-scenes
    • 高级数学可视化:https://github.com/3b1b/manim
  3. 视频教程

    • "Manim教程"系列(B站多位UP主有优质内容)
    • 3Blue1Brown的幕后制作解析视频

12.2 性能优化进阶

对于需要渲染超长或超高质量动画的情况:

  1. 分布式渲染: 使用Manim的-j参数指定多线程渲染:

    manim -p -qk -j 8 my_animation.py MyScene
  2. 云渲染方案

    • 使用AWS Batch或Google Cloud Batch提交渲染任务
    • 按需租用GPU实例(如AWS G4dn实例)
  3. 自定义着色器: 对于OpenGL渲染器,可以编写自定义GLSL着色器实现特殊扭曲效果:

class ShaderTwist(ThreeDScene): def construct(self): self.set_camera_orientation(phi=75*DEGREES) shader = Surface( lambda u,v: np.array([u,v,0]), u_range=[-2,2], v_range=[-2,2] ) shader.shader = """ vec3 distort(vec3 p, float t) { float angle = t * p.y; return vec3( p.x * cos(angle) - p.y * sin(angle), p.x * sin(angle) + p.y * cos(angle), p.z + 0.5*sin(angle) ); } void vertex() { vec3 pos = distort(position.xyz, time); gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); } """ self.play(Create(shader)) self.play( shader.animate.set_shader_uniform("time", 1.0), run_time=3 )

13. 创意扭曲特效合集

13.1 螺旋扭曲场

创建动态变化的螺旋扭曲场,影响多个对象:

class SpiralField(Scene): def construct(self): # 创建多个对象 objects = VGroup(*[ Square(), Circle(), Triangle(), RegularPolygon(5) ]) objects.arrange_in_grid(2,2, buff=1) self.play(Create(objects)) # 定义螺旋场函数 def spiral_field(p, t): center = np.array([0,0,0]) r = np.linalg.norm(p[:2]-center[:2]) theta = np.arctan2(p[1]-center[1], p[0]-center[0]) twist = t * (1 + 0.3*r) return np.array([ (p[0]-center[0])*np.cos(twist) - (p[1]-center[1])*np.sin(twist) + center[0], (p[0]-center[0])*np.sin(twist) + (p[1]-center[1])*np.cos(twist) + center[1], p[2] ]) # 应用动态扭曲 for t in np.linspace(0, 2*PI, 48): self.play( *[ obj.animate.apply_function( lambda p, t=t: spiral_field(p, t/8) ) for obj in objects ], run_time=1/24, rate_func=linear )

13.2 流体动力学模拟

模拟流体中的扭曲效果:

class FluidTwist(Scene): def construct(self): # 创建粒子系统 particles = VGroup(*[ Dot(radius=0.05, color=BLUE) for _ in range(200) ]) # 随机初始位置 for p in particles: p.move_to(np.random.uniform(-5,5,3)) self.add(particles) # 定义流体运动 def fluid_flow(p, t): return np.array([ p[0] + 0.1*np.sin(p[1] + t), p[1] + 0.1*np.cos(p[0] + t*0.7), p[2] + 0.05*np.sin(p[0]*p[1] + t*1.3) ]) # 更新函数 def update_particles(mob, dt): t = self.renderer.time for p in mob: new_pos = fluid_flow(p.get_center(), t) p.move_to(new_pos) particles.add_updater(update_particles) self.wait(8) particles.remove_updater(update_particles) # 添加突然的扭曲效果 self.play( particles.animate.apply_function( lambda p: [ p[0] * (1 + 0.5*np.sin(p[1])), p[1] * (1 + 0.5*np.cos(p[0])), p[2] ] ), run_time=2 )

14. 技术局限与替代方案

14.1 Manim的局限性

虽然Manim功能强大,但在扭曲特效方面仍有局限:

  1. 复杂变形精度问题

    • 极高阶扭曲可能导致网格自交
    • 解决方案:使用更精细的网格或分段变形
  2. 实时交互限制

    • Manim主要面向预渲染动画
    • 替代方案:导出到PyOpenGL或Unity实现交互
  3. 物理模拟不足

    • 内置物理功能有限
    • 解决方案:集成Pymunk或Taichi等物理引擎

14.2 备选技术方案

当Manim无法满足需求时,可以考虑:

  1. Blender+Python脚本

    • 更强大的3D建模和动画能力
    • 通过Python API实现程序化控制
  2. Matplotlib的3D动画

    • 更适合科研级精确可视化
    • 使用FuncAnimation创建基础扭曲动画
  3. WebGL/Three.js

    • 创建交互式网页可视化
    • 适合在线教学平台集成

15. 项目经验与心得分享

在实际教学中使用扭曲特效多年,我总结了这些实用经验:

  1. 教学节奏控制

    • 复杂扭曲动画要分步展示
    • 先用慢速完整播放,再分解讲解
    • 关键帧暂停强调重要概念
  2. 色彩编码技巧

    • 用颜色区分变形前后状态
    • 高亮显示固定点或不变区域
    • 渐变色表示扭曲强度梯度
  3. 学生常见困惑点

    • 混淆局部旋转和全局旋转
    • 不理解参数化曲面的u,v方向
    • 对连续变形概念理解困难

针对这些问题,我通常会:

  • 添加坐标轴指示器
  • 在变形过程中保持参考网格
  • 使用箭头标记特征点运动轨迹

最后分享一个实用小技巧:在制作复杂扭曲动画时,先创建简化版的线框模型预览效果,确认无误后再渲染完整细节版本,可以节省大量开发时间。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 17:25:00

智能车竞赛源码怎么读?一条数据链路看懂图像与PID控制

简介:面向智能汽车竞赛参赛者与嵌入式开发学习者的合集资料,内容覆盖全国大学生智能车竞赛的整车设计方案、程序源码、构建工程与赛后复盘记录。压缩包内共147个文件,核心包括C/C源码(.cpp/.hpp/.c)、CMake与VS工程配置…

作者头像 李华
网站建设 2026/9/11 17:23:49

2026年7月南京市秦淮区二手房价格深度分析报告

摘要本报告基于2026年7月南京市秦淮区实际成交的二手房案例数据,对该区域二手房市场的价格走势、板块分化、户型偏好及未来趋势进行深度分析。报告显示,2026年7月秦淮区二手房市场整体呈现“量稳价微升”的态势,核心学区房与优质地段房源价格…

作者头像 李华
网站建设 2026/9/11 17:23:39

固件功能不够用?ArduPilot Lua脚本救场

固件功能不够用?ArduPilot Lua脚本救场 【免费下载链接】ardupilot ArduPlane, ArduCopter, ArduRover, ArduSub source 项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot ArduPilot Lua脚本让你在飞控上直接写逻辑:低电量喊话、巡检打灯、临时改飞行行为,…

作者头像 李华
网站建设 2026/9/11 17:22:49

Windows 部署大模型 不联网 本地离线推理

Ollama:本地模型运行引擎 代码模型 (根据自身需求选用) 此处 以 qwen2.5-coder:7b-instruct 为例 (后来需要不联网翻译一些资料,用的是 translategemma:4b模型) Open WebUI:本地网页界面&am…

作者头像 李华
网站建设 2026/9/11 17:22:14

Java Swing船舶管理系统:从JDBC到FTP上报的存量系统解析与升级实践

简介:国内航运企业船舶管理系统是一套面向中小航运企业船舶管理场景的完整Java项目源码,适用于正在学习企业级管理系统开发的学生或初级程序员。资源包共69个文件,包含20个Java源文件、38个已编译的class文件、必要jar依赖及Excel数据文件&am…

作者头像 李华