载入中...
搜索中...
未找到
数学模块

数学模块

脚本入口: eve.Math()

提供向量、矩阵、几何、噪声、随机数、插值和缓动工具。2D/3D 对象的**点选、重叠与射线检测**也放在本模块(轻量几何测试);带刚体/接触响应的模拟见 Physics,屏幕坐标换算见 Graphics 的 Camera2D/Camera3D。

基本用法

local math = eve.Math();
math.setRandomSeed(42);
local p = math.newVec2(10, 20);
local n = math.noise2(p.getX(), p.getY());

对象关系与调用时机

Math 是算法与随机状态入口;Vec2/Vec3/Mat4 是值对象;noise、random、ease、Bezier 和几何测试由模块提供。需要确定性的系统应拥有独立且明确 seed 的 Math 状态。

目标导向指南

可复现随机地图

生成前 setRandomSeed(seed),所有随机选择使用同一 Math 实例;存档只需记录 seed 和玩家改动。不要用时间 seed 做需要联网同步的逻辑。

平滑移动和程序噪声

用 lerp/smoothstep/ease 做相机与 UI 插值;noise2() / fractal noise 适合高度图,输入坐标乘 frequency 控制尺度。Vec/Mat 对象用于变换组合,热点循环避免反复分配临时对象。

2D 点击拾取与重叠

鼠标/触摸先经 Camera2D.screenToWorld* 得到世界坐标,再用:

  • pointInCircle / pointInRect — 点选精灵或按钮
  • circlesOverlap / rectsOverlap / circleRectOverlap — 无物理的碰撞/触发
  • raycastCircle2 / raycastRect2 — 子弹、视线;命中点 = o + t * d,未命中返回 -1
  • segmentsIntersect — 线段相交(弹道、边缘)
local mx = mouse.getX();
local my = mouse.getY();
local wx = cam2d.screenToWorldX(mx, my, gfx.getWidth(), gfx.getHeight());
local wy = cam2d.screenToWorldY(mx, my, gfx.getWidth(), gfx.getHeight());
if (math.pointInRect(wx, wy, spriteX, spriteY, spriteW, spriteH)) {
// picked
}

3D 射线拾取

Camera3D.screenToRay 生成世界射线后,用 raycastSphere / raycastBox / raycastPlane 测距;t >= 0 表示命中。多个候选取最小 t

cam3d.screenToRay(mouse.getX(), mouse.getY(), gfx.getWidth(), gfx.getHeight());
local ox = cam3d.getScreenRayOriginX();
local oy = cam3d.getScreenRayOriginY();
local oz = cam3d.getScreenRayOriginZ();
local dx = cam3d.getScreenRayDirX();
local dy = cam3d.getScreenRayDirY();
local dz = cam3d.getScreenRayDirZ();
local t = math.raycastSphere(ox, oy, oz, dx, dy, dz, cx, cy, cz, radius);
if (t >= 0) {
local hx = ox + dx * t;
local hy = oy + dy * t;
local hz = oz + dz * t;
}

常见问题

  • 客户端各自用时间 seed,造成联机状态分叉。
  • 度和弧度混用。
  • 未归一化方向向量就用于速度或点积判断。
  • 射线 API 的 t 是参数:hit = origin + t * dirdir 不必单位化,线段检测时用 dir = B - A 并要求 t ∈ [0,1]
  • 把 Math 几何测试当成刚体物理:需要接触事件、摩擦或传感器时用 Physics。

API 快查

下列方法名来自当前 Squirrel 绑定;同一模块创建的辅助对象(例如 WorldBodySource)的方法也列在这里。

  • add()angle()angle2()angleBetween2()approach()bezierCubic()bezierCubic2X()bezierCubic2Y()
  • bezierQuadratic()bezierQuadratic2X()bezierQuadratic2Y()bias()bilinear()boxesOverlap()cartesianAngle()
  • cartesianRadius()circleRectOverlap()circlesOverlap()clamp()clone()closestPointOnSegment2X()closestPointOnSegment2Y()closestPointOnSegment3X()
  • closestPointOnSegment3Y()closestPointOnSegment3Z()cross()cross2()degToRad()distance2()distance3()distanceTo()
  • dot()dot2()dot3()ease()fbm2()fbm3()fract()gain()
  • get()getName()getRandomSeed()getX()getY()getZ()hash1()hash2()
  • hash3()identity()inverseLerp()length()length2()length3()lengthSquared()lerp()
  • lerpAngle()lerpTo()multiplied()multiply()newMat4()newMat4RotationZ()newMat4Scale()newMat4Translation()
  • newVec2()newVec3()noise1()noise2()noise3()normalize()normalize2X()normalize2Y()
  • normalize3X()normalize3Y()normalize3Z()normalized()perlin2()perlin3()pingPong()pointInBox()
  • pointInCircle()pointInRect()pointInSphere()polarX()polarY()quantize()radToDeg()random()
  • randomGaussian()randomInt()randomRange()raycastBox()raycastCircle2()raycastPlane()raycastRect2()raycastSphere()
  • rectsOverlap()remap()ridged2()ridged3()rotate2X()rotate2Y()rotateX()rotateY()
  • rotateZ()scale()segmentsIntersect()set()setRandomSeed()setRandomSeedFromTime()setX()setY()
  • setZ()sign()smootherstep()smoothstep()snap()spheresOverlap()step()sub()
  • transformPoint2()transformVec3()translate()turbulence2()voronoi2()voronoiEdge2()warpNoise2()wrap()

使用要点

  • 模块对象和它创建的资源对象应保存在全局或实体状态中,不要在每帧重复创建。
  • update(dt) 的系统应在 eve_update 调用;绘制方法应在 eve_render 调用。
  • 参数约束、默认值和返回类型以对应模块头文件及 addFunc 绑定为准;本文 API 快查与当前源码同步生成。

源码: src/modules/math/ 相关测试:test/ 中搜索 math