diff --git a/source/Behavior/Behavior.ts b/source/Behavior/Behavior.ts index 90e7119..0309072 100644 --- a/source/Behavior/Behavior.ts +++ b/source/Behavior/Behavior.ts @@ -2,10 +2,12 @@ import { BehaviorRecorder, IAnyBehaviorRecorder } from "@Model/Behavior"; import { Template } from "./Template"; import { Dynamics } from "./Dynamics"; import { Brownian } from "./Brownian"; +import { BoundaryConstraint } from "./BoundaryConstraint"; const AllBehaviors: IAnyBehaviorRecorder[] = [ new BehaviorRecorder(Dynamics), - new BehaviorRecorder(Brownian) + new BehaviorRecorder(Brownian), + new BehaviorRecorder(BoundaryConstraint) ] /** @@ -51,6 +53,4 @@ function categoryBehaviors(behaviors: IAnyBehaviorRecorder[]): ICategory[] { return res; } -console.log(AllBehaviorsWithCategory) - export { AllBehaviors, AllBehaviorsWithCategory, ICategory as ICategoryBehavior }; \ No newline at end of file diff --git a/source/Behavior/BoundaryConstraint.ts b/source/Behavior/BoundaryConstraint.ts new file mode 100644 index 0000000..4e36d70 --- /dev/null +++ b/source/Behavior/BoundaryConstraint.ts @@ -0,0 +1,74 @@ +import { Behavior } from "@Model/Behavior"; +import { Group } from "@Model/Group"; +import { Individual } from "@Model/Individual"; +import { Label } from "@Model/Label"; +import { Model } from "@Model/Model"; +import { Range } from "@Model/Range"; + +type IBoundaryConstraintBehaviorParameter = { + range: "LR" +} + +type IBoundaryConstraintBehaviorEvent = {} + +class BoundaryConstraint extends Behavior { + + public override behaviorId: string = "BoundaryConstraint"; + + public override behaviorName: string = "$Title"; + + public override iconName: string = "Running"; + + public override describe: string = "$Intro"; + + public override category: string = "$Physics"; + + public override parameterOption = { + range: { + type: "LR", + name: "$range", + defaultValue: undefined + } + }; + + public override terms: Record> = { + "$Title": { + "ZH_CN": "边界约束", + "EN_US": "Boundary constraint" + }, + "$Intro": { + "ZH_CN": "个体越出边界后将主动返回", + "EN_US": "Individuals will return actively after crossing the border" + } + }; + + public effect(individual: Individual, group: Group, model: Model, t: number): void { + let rangeList: Range[] = []; + if (this.parameter.range instanceof Range) { + rangeList.push(this.parameter.range); + } + if (this.parameter.range instanceof Label) { + rangeList = model.getObjectByLabel(this.parameter.range).filter((obj) => { + return obj instanceof Range + }) as any; + } + for (let i = 0; i < rangeList.length; i++) { + + let rx = rangeList[i].position[0] - individual.position[0]; + let ry = rangeList[i].position[1] - individual.position[1]; + let rz = rangeList[i].position[2] - individual.position[2]; + + let ox = Math.abs(rx) > rangeList[i].radius[0]; + let oy = Math.abs(ry) > rangeList[i].radius[1]; + let oz = Math.abs(rz) > rangeList[i].radius[2]; + + individual.applyForce( + ox ? rx : 0, + oy ? ry : 0, + oz ? rz : 0 + ) + } + } +} + +export { BoundaryConstraint }; \ No newline at end of file diff --git a/source/Behavior/Brownian.ts b/source/Behavior/Brownian.ts index 094d00b..c468d20 100644 --- a/source/Behavior/Brownian.ts +++ b/source/Behavior/Brownian.ts @@ -42,7 +42,7 @@ class Brownian extends Behavior 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; @@ -107,15 +118,22 @@ class Dynamics extends Behavior 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; }; } diff --git a/source/Model/Actuator.ts b/source/Model/Actuator.ts index 83ba8ad..64e93b5 100644 --- a/source/Model/Actuator.ts +++ b/source/Model/Actuator.ts @@ -19,7 +19,7 @@ class Actuator extends Emitter { /** * 模拟帧率 */ - public fps: number = 24; + public fps: number = 36; /** * 仿真是否进行 @@ -56,7 +56,7 @@ class Actuator extends Emitter { */ private alignTimer: number = 0; - public tickerType: 1 | 2 = 1; + public tickerType: 1 | 2 = 2; private ticker(t: number) { if (this.startFlag && t !== 0) { diff --git a/source/Page/SimulatorWeb/SimulatorWeb.tsx b/source/Page/SimulatorWeb/SimulatorWeb.tsx index 9a84e5d..a006f17 100644 --- a/source/Page/SimulatorWeb/SimulatorWeb.tsx +++ b/source/Page/SimulatorWeb/SimulatorWeb.tsx @@ -59,8 +59,12 @@ class SimulatorWeb extends Component { dynamic.name = "dynamic"; let brownian = this.status.model.addBehavior(AllBehaviors[1]); brownian.name = "brownian"; + let boundary = this.status.model.addBehavior(AllBehaviors[2]); + boundary.name = "boundary"; + boundary.parameter.range = this.status.model.allRangeLabel; group.addBehavior(dynamic); group.addBehavior(brownian); + group.addBehavior(boundary); } (window as any).s = this;