living-together/source/Behavior/PhysicsDynamics.ts
2022-04-10 18:14:16 +08:00

136 lines
4.7 KiB
TypeScript

import { Behavior } from "@Model/Behavior";
import Group from "@Model/Group";
import Individual from "@Model/Individual";
import { Model } from "@Model/Model";
type IPhysicsDynamicsBehaviorParameter = {
mass: "number",
maxAcceleration: "number",
maxVelocity: "number",
resistance: "number",
limit: "boolean"
}
type IPhysicsDynamicsBehaviorEvent = {}
class PhysicsDynamics extends Behavior<IPhysicsDynamicsBehaviorParameter, IPhysicsDynamicsBehaviorEvent> {
public override behaviorId: string = "PhysicsDynamics";
public override behaviorName: string = "$Title";
public override iconName: string = "SliderHandleSize";
public override describe: string = "$Intro";
public override category: string = "$Physics";
public override parameterOption = {
mass: { name: "$Mass", type: "number", defaultValue: 1, numberStep: .01, numberMin: .001 },
resistance: { name: "$Resistance", type: "number", defaultValue: 0.5, numberStep: .1, numberMin: 0 },
limit: { name: "$Limit", type: "boolean", defaultValue: true },
maxAcceleration: {
name: "$Max.Acceleration", type: "number", defaultValue: 5,
numberStep: .1, numberMin: 0, condition: { key: "limit", value: true }
},
maxVelocity: {
name: "$Max.Velocity", type: "number", defaultValue: 10,
numberStep: .1, numberMin: 0, condition: { key: "limit", value: true }
},
};
public override finalEffect = (individual: Individual, group: Group, model: Model, t: number): void => {
// 计算当前速度
const currentV = individual.vectorLength(individual.velocity);
// 计算阻力
const resistance = currentV * currentV * this.parameter.resistance;
// 应用阻力
if (currentV) {
individual.applyForce(
(- individual.velocity[0] / currentV) * resistance,
(- individual.velocity[1] / currentV) * resistance,
(- individual.velocity[2] / currentV) * resistance
);
}
// 计算加速度
individual.acceleration[0] = individual.force[0] / this.parameter.mass;
individual.acceleration[1] = individual.force[1] / this.parameter.mass;
individual.acceleration[2] = individual.force[2] / this.parameter.mass;
// 加速度约束
if (this.parameter.limit) {
const lengthA = individual.vectorLength(individual.acceleration);
if (lengthA > this.parameter.maxAcceleration) {
individual.acceleration[0] = individual.acceleration[0] * this.parameter.maxAcceleration / lengthA;
individual.acceleration[1] = individual.acceleration[1] * this.parameter.maxAcceleration / lengthA;
individual.acceleration[2] = individual.acceleration[2] * this.parameter.maxAcceleration / lengthA;
}
}
// 计算速度
individual.velocity[0] = individual.velocity[0] + individual.acceleration[0] * t;
individual.velocity[1] = individual.velocity[1] + individual.acceleration[1] * t;
individual.velocity[2] = individual.velocity[2] + individual.acceleration[2] * t;
// 速度约束
if (this.parameter.limit) {
const lengthV = individual.vectorLength(individual.velocity);
if (lengthV > this.parameter.maxVelocity) {
individual.velocity[0] = individual.velocity[0] * this.parameter.maxVelocity / lengthV;
individual.velocity[1] = individual.velocity[1] * this.parameter.maxVelocity / lengthV;
individual.velocity[2] = individual.velocity[2] * this.parameter.maxVelocity / lengthV;
}
}
// 应用速度
individual.position[0] = individual.position[0] + individual.velocity[0] * t;
individual.position[1] = individual.position[1] + individual.velocity[1] * t;
individual.position[2] = individual.position[2] + individual.velocity[2] * t;
// 清除受力
individual.force[0] = 0;
individual.force[1] = 0;
individual.force[2] = 0;
};
public override terms: Record<string, Record<string, string>> = {
"$Title": {
"ZH_CN": "物理动力学",
"EN_US": "Physics dynamics"
},
"$Intro": {
"ZH_CN": "一切按照物理规则运动物体的行为, 按照牛顿经典物理运动公式执行。",
"EN_US": "The behavior of all moving objects according to physical rules is carried out according to Newton's classical physical motion formula."
},
"$Limit": {
"ZH_CN": "开启限制",
"EN_US": "Enable limit"
},
"$Mass": {
"ZH_CN": "质量 (Kg)",
"EN_US": "Mass (Kg)"
},
"$Max.Acceleration": {
"ZH_CN": "最大加速度 (m/s²)",
"EN_US": "Maximum acceleration (m/s²)"
},
"$Max.Velocity": {
"ZH_CN": "最大速度 (m/s)",
"EN_US": "Maximum velocity (m/s)"
},
"$Resistance": {
"ZH_CN": "阻力系数",
"EN_US": "Resistance coefficient"
},
"$Physics": {
"ZH_CN": "物理",
"EN_US": "Physics"
}
};
}
export { PhysicsDynamics };