Skip to content

Commit

Permalink
Physics decomposed to new Interface.
Browse files Browse the repository at this point in the history
  • Loading branch information
Smoren committed Mar 28, 2024
1 parent 5254d87 commit ebce73d
Show file tree
Hide file tree
Showing 14 changed files with 72 additions and 40 deletions.
2 changes: 2 additions & 0 deletions src/lib/example/variants/2d/butterfly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { createBaseWorldConfig } from "@/lib/config/world";
import { create2dBaseInitialConfig } from "@/lib/config/initial";
import { create2dButterfly } from "@/lib/config/atoms";
import { Simulation } from "../../../simulation";
import { PhysicModelV1 } from "@/lib/physics/v1";

const WORLD_CONFIG: WorldConfig = createBaseWorldConfig();
const TYPES_CONFIG: TypesConfig = createBaseTypesConfig();
Expand All @@ -19,6 +20,7 @@ export function create2dSimulationButterfly() {
worldConfig: WORLD_CONFIG,
typesConfig: TYPES_CONFIG,
initialConfig: INITIAL_CONFIG,
physicModel: new PhysicModelV1(WORLD_CONFIG, TYPES_CONFIG),
atomsFactory: create2dButterfly,
drawer: create2dDrawer('canvas', WORLD_CONFIG, TYPES_CONFIG),
});
Expand Down
2 changes: 2 additions & 0 deletions src/lib/example/variants/2d/const-types-distribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { createBaseWorldConfig } from "@/lib/config/world";
import { create2dBaseInitialConfig } from "@/lib/config/initial";
import { create2dRandomDistribution } from "@/lib/config/atoms";
import { Simulation } from "../../../simulation";
import { PhysicModelV1 } from "@/lib/physics/v1";

const WORLD_CONFIG: WorldConfig = createBaseWorldConfig();
const TYPES_CONFIG: TypesConfig = createBaseTypesConfig();
Expand All @@ -19,6 +20,7 @@ export function create2dSimulationWithConstTypes() {
worldConfig: WORLD_CONFIG,
typesConfig: TYPES_CONFIG,
initialConfig: INITIAL_CONFIG,
physicModel: new PhysicModelV1(WORLD_CONFIG, TYPES_CONFIG),
atomsFactory: create2dRandomDistribution,
drawer: create2dDrawer('canvas', WORLD_CONFIG, TYPES_CONFIG),
});
Expand Down
2 changes: 2 additions & 0 deletions src/lib/example/variants/2d/random-types-distribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { createBaseWorldConfig } from "@/lib/config/world";
import { create2dBaseInitialConfig } from "@/lib/config/initial";
import { create2dRandomDistribution } from "@/lib/config/atoms";
import { Simulation } from "../../../simulation";
import { PhysicModelV1 } from "@/lib/physics/v1";

const WORLD_CONFIG: WorldConfig = createBaseWorldConfig();
const TYPES_CONFIG: TypesConfig = createRandomTypesConfig({
Expand All @@ -30,6 +31,7 @@ export function create2dSimulationWithRandomTypes() {
worldConfig: WORLD_CONFIG,
typesConfig: TYPES_CONFIG,
initialConfig: INITIAL_CONFIG,
physicModel: new PhysicModelV1(WORLD_CONFIG, TYPES_CONFIG),
atomsFactory: create2dRandomDistribution,
drawer: create2dDrawer('canvas', WORLD_CONFIG, TYPES_CONFIG),
});
Expand Down
2 changes: 2 additions & 0 deletions src/lib/example/variants/3d/butterfly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { create3dBaseInitialConfig } from "@/lib/config/initial";
import { create3Butterfly } from "@/lib/config/atoms";
import { Simulation } from "../../../simulation";
import { create3dDrawer } from "../../../drawer/3d";
import { PhysicModelV1 } from "@/lib/physics/v1";

const WORLD_CONFIG: WorldConfig = createBaseWorldConfig();
const TYPES_CONFIG: TypesConfig = createBaseTypesConfig();
Expand All @@ -19,6 +20,7 @@ export function create3dSimulationButterfly() {
worldConfig: WORLD_CONFIG,
typesConfig: TYPES_CONFIG,
initialConfig: INITIAL_CONFIG,
physicModel: new PhysicModelV1(WORLD_CONFIG, TYPES_CONFIG),
atomsFactory: create3Butterfly,
drawer: create3dDrawer('canvas', WORLD_CONFIG, TYPES_CONFIG),
});
Expand Down
2 changes: 2 additions & 0 deletions src/lib/example/variants/3d/const-types-distribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { create3dBaseInitialConfig } from "@/lib/config/initial";
import { create3dRandomDistribution } from "@/lib/config/atoms";
import { Simulation } from "../../../simulation";
import { create3dDrawer } from "../../../drawer/3d";
import { PhysicModelV1 } from "@/lib/physics/v1";

const WORLD_CONFIG: WorldConfig = createBaseWorldConfig();
const TYPES_CONFIG: TypesConfig = createBaseTypesConfig();
Expand All @@ -19,6 +20,7 @@ export function create3dSimulationWithConstTypes() {
worldConfig: WORLD_CONFIG,
typesConfig: TYPES_CONFIG,
initialConfig: INITIAL_CONFIG,
physicModel: new PhysicModelV1(WORLD_CONFIG, TYPES_CONFIG),
atomsFactory: create3dRandomDistribution,
drawer: create3dDrawer('canvas', WORLD_CONFIG, TYPES_CONFIG),
});
Expand Down
2 changes: 2 additions & 0 deletions src/lib/example/variants/3d/random-types-distribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { create3dBaseInitialConfig } from "@/lib/config/initial";
import { create3dRandomDistribution } from "@/lib/config/atoms";
import { Simulation } from "../../../simulation";
import { create3dDrawer } from "../../../drawer/3d";
import { PhysicModelV1 } from "@/lib/physics/v1";

const WORLD_CONFIG: WorldConfig = createBaseWorldConfig();
const TYPES_CONFIG: TypesConfig = createRandomTypesConfig({
Expand All @@ -30,6 +31,7 @@ export function create3dSimulationWithRandomTypes() {
worldConfig: WORLD_CONFIG,
typesConfig: TYPES_CONFIG,
initialConfig: INITIAL_CONFIG,
physicModel: new PhysicModelV1(WORLD_CONFIG, TYPES_CONFIG),
atomsFactory: create3dRandomDistribution,
drawer: create3dDrawer('canvas', WORLD_CONFIG, TYPES_CONFIG),
});
Expand Down
30 changes: 0 additions & 30 deletions src/lib/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,36 +73,6 @@ export class RulesHelper implements RulesHelperInterface {
return this._isLinkRedundant(lhs, rhs) || this._isLinkRedundant(rhs, lhs);
}

getGravityForce(lhs: AtomInterface, rhs: AtomInterface, dist2: number): number {
let multiplier: number;

if (dist2 < this.getAtomsRadiusSum() ** 2) {
multiplier = -this.WORLD_CONFIG.BOUNCE_FORCE_MULTIPLIER;
} else if (!lhs.bonds.has(rhs)) {
multiplier = this.WORLD_CONFIG.GRAVITY_FORCE_MULTIPLIER * this.TYPES_CONFIG.GRAVITY[lhs.type][rhs.type];
} else {
multiplier = this.WORLD_CONFIG.GRAVITY_FORCE_MULTIPLIER * this.TYPES_CONFIG.LINK_GRAVITY[lhs.type][rhs.type];
}

const result = multiplier * this.WORLD_CONFIG.SPEED / dist2;

if (Math.abs(result) > this.WORLD_CONFIG.MAX_FORCE) {
return Math.sign(result) * this.WORLD_CONFIG.MAX_FORCE;
}

return result;
}

getLinkForce(): number {
const result = Math.min(this.WORLD_CONFIG.LINK_FORCE_MULTIPLIER * this.WORLD_CONFIG.SPEED);

if (Math.abs(result) > this.WORLD_CONFIG.MAX_FORCE) {
return Math.sign(result) * this.WORLD_CONFIG.MAX_FORCE;
}

return result;
}

getAtomsRadiusSum(): number {
return this.WORLD_CONFIG.ATOM_RADIUS * 2;
}
Expand Down
14 changes: 6 additions & 8 deletions src/lib/interaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,28 @@ import type { LinkManagerInterface, RulesHelperInterface } from './types/helpers
import type { AtomInterface, LinkInterface } from './types/atomic';
import type { NumericVector, VectorInterface } from './vector/types';
import type { InteractionManagerInterface } from './types/interaction';
import type { PhysicModelInterface } from "./types/interaction";
import { toVector } from './vector';

export class InteractionManager implements InteractionManagerInterface {
private readonly WORLD_CONFIG: WorldConfig;
private readonly TYPES_CONFIG: TypesConfig;
private readonly linkManager: LinkManagerInterface;
private readonly physicModel: PhysicModelInterface;
private readonly ruleHelper: RulesHelperInterface;
private time: number;

constructor(
worldConfig: WorldConfig,
typesConfig: TypesConfig,
linkManager: LinkManagerInterface,
physicModel: PhysicModelInterface,
ruleHelper: RulesHelperInterface,
) {
this.WORLD_CONFIG = worldConfig;
this.TYPES_CONFIG = typesConfig;
this.linkManager = linkManager;
this.physicModel = physicModel;
this.ruleHelper = ruleHelper;
this.time = 0;
}
Expand Down Expand Up @@ -90,18 +94,12 @@ export class InteractionManager implements InteractionManagerInterface {
}

const dist = Math.sqrt(dist2);
const gravityForce = this.ruleHelper.getGravityForce(lhs, rhs, dist2);
const gravityForce = this.physicModel.getGravityForce(lhs, rhs, dist2);
for (let i=0; i<distVector.length; ++i) {
distVector[i] = distVector[i] / dist * gravityForce;
}
lhs.speed.add(distVector);

// lhs.speed.add(
// toVector(distVector)
// .normalize()
// .mul(this.ruleHelper.getGravityForce(lhs, rhs, dist2)),
// );

if (
!lhs.bonds.has(rhs) &&
this.ruleHelper.canLink(lhs, rhs) &&
Expand Down Expand Up @@ -139,7 +137,7 @@ export class InteractionManager implements InteractionManagerInterface {
distVector: VectorInterface,
): void {
lhs.speed.add(
distVector.normalize().mul(this.ruleHelper.getLinkForce(lhs, rhs, dist2)),
distVector.normalize().mul(this.physicModel.getLinkForce(lhs, rhs, dist2)),
);
}

Expand Down
43 changes: 43 additions & 0 deletions src/lib/physics/v1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { TypesConfig, WorldConfig } from "../types/config";
import type { AtomInterface } from "../types/atomic";
import type { PhysicModelInterface } from "../types/interaction";

export class PhysicModelV1 implements PhysicModelInterface {
private WORLD_CONFIG: WorldConfig;
private TYPES_CONFIG: TypesConfig;

constructor(worldConfig: WorldConfig, typesConfig: TypesConfig) {
this.WORLD_CONFIG = worldConfig;
this.TYPES_CONFIG = typesConfig;
}

getGravityForce(lhs: AtomInterface, rhs: AtomInterface, dist2: number): number {
let multiplier: number;

if (dist2 < (this.WORLD_CONFIG.ATOM_RADIUS * 2) ** 2) {
multiplier = -this.WORLD_CONFIG.BOUNCE_FORCE_MULTIPLIER;
} else if (!lhs.bonds.has(rhs)) {
multiplier = this.WORLD_CONFIG.GRAVITY_FORCE_MULTIPLIER * this.TYPES_CONFIG.GRAVITY[lhs.type][rhs.type];
} else {
multiplier = this.WORLD_CONFIG.GRAVITY_FORCE_MULTIPLIER * this.TYPES_CONFIG.LINK_GRAVITY[lhs.type][rhs.type];
}

const result = multiplier * this.WORLD_CONFIG.SPEED / dist2;

if (Math.abs(result) > this.WORLD_CONFIG.MAX_FORCE) {
return Math.sign(result) * this.WORLD_CONFIG.MAX_FORCE;
}

return result;
}

getLinkForce(): number {
const result = Math.min(this.WORLD_CONFIG.LINK_FORCE_MULTIPLIER * this.WORLD_CONFIG.SPEED);

if (Math.abs(result) > this.WORLD_CONFIG.MAX_FORCE) {
return Math.sign(result) * this.WORLD_CONFIG.MAX_FORCE;
}

return result;
}
}
1 change: 1 addition & 0 deletions src/lib/simulation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export class Simulation implements SimulationInterface {
this.config.worldConfig,
this.config.typesConfig,
this.linkManager,
this.config.physicModel,
new RulesHelper(this.config.typesConfig, this.config.worldConfig),
);
this.clusterManager = new ClusterManager(this.config.worldConfig.MAX_INTERACTION_RADIUS);
Expand Down
2 changes: 0 additions & 2 deletions src/lib/types/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,5 @@ export interface LinkManagerInterface extends Iterable<LinkInterface> {
export interface RulesHelperInterface {
canLink(lhs: AtomInterface, rhs: AtomInterface): boolean;
isLinkRedundant(lhs: AtomInterface, rhs: AtomInterface): boolean;
getGravityForce(lhs: AtomInterface, rhs: AtomInterface, dist2: number): number;
getLinkForce(lhs: AtomInterface, rhs: AtomInterface, dist2: number): number;
getAtomsRadiusSum(lhs: AtomInterface, rhs: AtomInterface): number;
}
5 changes: 5 additions & 0 deletions src/lib/types/interaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ export interface InteractionManagerInterface {
interactAtomsStep1(atom: AtomInterface, neighbour: AtomInterface): void;
interactAtomsStep2(atom: AtomInterface, neighbour: AtomInterface): void;
}

export interface PhysicModelInterface {
getGravityForce(lhs: AtomInterface, rhs: AtomInterface, dist2: number): number;
getLinkForce(lhs: AtomInterface, rhs: AtomInterface, dist2: number): number;
}
2 changes: 2 additions & 0 deletions src/lib/types/simulation.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import type { InitialConfig, TypesConfig, WorldConfig } from './config';
import type { AtomInterface } from './atomic';
import type { DrawerInterface } from './drawer';
import type { PhysicModelInterface } from "./interaction";

export type SimulationConfig = {
worldConfig: WorldConfig;
typesConfig: TypesConfig;
initialConfig: InitialConfig;
physicModel: PhysicModelInterface;
atomsFactory: (
worldConfig: WorldConfig,
typesConfig: TypesConfig,
Expand Down
3 changes: 3 additions & 0 deletions src/store/simulation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { create2dRandomDistribution, create3dRandomDistribution } from "@/lib/co
import { create3dDrawer } from "@/lib/drawer/3d";
import { create2dDrawer } from "@/lib/drawer/2d";
import type { SimulationInterface } from "@/lib/types/simulation";
import { PhysicModelV1 } from "@/lib/physics/v1";

export const useSimulationStore = defineStore("simulation", () => {
const configStore = useConfigStore();
Expand All @@ -31,6 +32,7 @@ export const useSimulationStore = defineStore("simulation", () => {
worldConfig: worldConfig,
typesConfig: typesConfig,
initialConfig: initialConfig,
physicModel: new PhysicModelV1(worldConfig, typesConfig),
atomsFactory: create3dRandomDistribution,
drawer: create3dDrawer('canvas3d', configStore.worldConfig, configStore.typesConfig),
});
Expand All @@ -51,6 +53,7 @@ export const useSimulationStore = defineStore("simulation", () => {
worldConfig: worldConfig,
typesConfig: typesConfig,
initialConfig: initialConfig,
physicModel: new PhysicModelV1(worldConfig, typesConfig),
atomsFactory: create2dRandomDistribution,
drawer: create2dDrawer('canvas2d', configStore.worldConfig, configStore.typesConfig),
});
Expand Down

0 comments on commit ebce73d

Please sign in to comment.