3 Commits
Author SHA1 Message Date
MrKBear 70ff9fa0ad Add setting option 2022-05-20 14:41:52 +08:00
MrKBear 4eb6637062 fix brownian behavior 2022-05-12 20:22:18 +08:00
MrKBear 8670b577f9 Add sample tracking behavior 2022-05-11 13:09:51 +08:00
7 changed files with 65 additions and 13 deletions
+10 -4
View File
@@ -132,7 +132,7 @@ class Brownian extends Behavior<IBrownianBehaviorParameter, IBrownianBehaviorEve
const vLen = individual.vectorLength(individual.velocity); const vLen = individual.vectorLength(individual.velocity);
// 随机旋转算法 // 随机旋转算法
if (vLen !== 0) { if (vLen > 0) {
randomDir = this.randomFocusRange( randomDir = this.randomFocusRange(
[ [
individual.velocity[0] / vLen, individual.velocity[0] / vLen,
@@ -141,6 +141,10 @@ class Brownian extends Behavior<IBrownianBehaviorParameter, IBrownianBehaviorEve
], ],
this.parameter.angle / 2 this.parameter.angle / 2
); );
if (isNaN(randomDir[0]) || isNaN(randomDir[1]) || isNaN(randomDir[2])) {
randomDir = this.randomFocus360()
}
} }
else { else {
@@ -153,10 +157,12 @@ class Brownian extends Behavior<IBrownianBehaviorParameter, IBrownianBehaviorEve
randomDir = this.randomFocus360() randomDir = this.randomFocus360()
} }
const randomLength = minStrength + Math.random() * (maxStrength - minStrength);
individual.applyForce( individual.applyForce(
minStrength + randomDir[0] * (maxStrength - minStrength), randomDir[0] * randomLength,
minStrength + randomDir[1] * (maxStrength - minStrength), randomDir[1] * randomLength,
minStrength + randomDir[2] * (maxStrength - minStrength) randomDir[2] * randomLength
); );
nextTime = minFrequency + Math.random() * (maxFrequency - minFrequency); nextTime = minFrequency + Math.random() * (maxFrequency - minFrequency);
+8 -2
View File
@@ -5,6 +5,7 @@ import { Model } from "@Model/Model";
type ISampleTrackingBehaviorParameter = { type ISampleTrackingBehaviorParameter = {
target: "CLG", target: "CLG",
key: "string",
strength: "number", strength: "number",
range: "number", range: "number",
angle: "number", angle: "number",
@@ -27,6 +28,7 @@ class SampleTracking extends Behavior<ISampleTrackingBehaviorParameter, ISampleT
public override parameterOption = { public override parameterOption = {
target: { type: "CLG", name: "$Target" }, target: { type: "CLG", name: "$Target" },
key: { type: "string", name: "$Key"},
range: { type: "number", name: "$Range", defaultValue: 4, numberMin: 0, numberStep: .1 }, range: { type: "number", name: "$Range", defaultValue: 4, numberMin: 0, numberStep: .1 },
angle: { type: "number", name: "$Angle", defaultValue: 180, numberMin: 0, numberMax: 360, numberStep: 5 }, angle: { type: "number", name: "$Angle", defaultValue: 180, numberMin: 0, numberMax: 360, numberStep: 5 },
strength: { type: "number", name: "$Strength", defaultValue: 1, numberMin: 0, numberStep: .1 }, strength: { type: "number", name: "$Strength", defaultValue: 1, numberMin: 0, numberStep: .1 },
@@ -81,7 +83,7 @@ class SampleTracking extends Behavior<ISampleTrackingBehaviorParameter, ISampleT
dirArr[i][0] += targetDir[0]; dirArr[i][0] += targetDir[0];
dirArr[i][1] += targetDir[1]; dirArr[i][1] += targetDir[1];
dirArr[i][2] += targetDir[2]; dirArr[i][2] += targetDir[2];
valArr[i] += targetIndividual.getData("Wastage.Pheromone") ?? 0; valArr[i] += targetIndividual.getData(this.parameter.key) ?? 0;
isFindNest = true; isFindNest = true;
} }
} }
@@ -90,7 +92,7 @@ class SampleTracking extends Behavior<ISampleTrackingBehaviorParameter, ISampleT
// 保存 // 保存
dirArr.push(targetDir); dirArr.push(targetDir);
valArr.push(targetIndividual.getData("Wastage.Pheromone") ?? 0); valArr.push(targetIndividual.getData(this.parameter.key) ?? 0);
} }
} }
}); });
@@ -124,6 +126,10 @@ class SampleTracking extends Behavior<ISampleTrackingBehaviorParameter, ISampleT
"ZH_CN": "追踪目标", "ZH_CN": "追踪目标",
"EN_US": "Tracking target" "EN_US": "Tracking target"
}, },
"$Key": {
"ZH_CN": "计算键值",
"EN_US": "Calculate key value"
},
"$Accuracy": { "$Accuracy": {
"ZH_CN": "采样精度", "ZH_CN": "采样精度",
"EN_US": "Sampling accuracy" "EN_US": "Sampling accuracy"
@@ -188,11 +188,6 @@ class CommandBar extends Component<IMixinSettingProps & IMixinStatusProps, IComm
this.props.status ? this.props.status.newLabel() : undefined; this.props.status ? this.props.status.newLabel() : undefined;
}} }}
/> />
<CommandButton
iconName="Camera"
i18NKey="Command.Bar.Camera.Info"
/>
</div> </div>
<div> <div>
<CommandButton <CommandButton
@@ -3,4 +3,6 @@
div.setting-popup { div.setting-popup {
width: 100%; width: 100%;
height: 100%; height: 100%;
box-sizing: border-box;
padding: 10px;
} }
+37 -2
View File
@@ -2,8 +2,11 @@ import { Component, ReactNode } from "react";
import { Popup } from "@Context/Popups"; import { Popup } from "@Context/Popups";
import { Theme } from "@Component/Theme/Theme"; import { Theme } from "@Component/Theme/Theme";
import { Localization } from "@Component/Localization/Localization"; import { Localization } from "@Component/Localization/Localization";
import { useSettingWithEvent, IMixinSettingProps, Themes } from "@Context/Setting";
import { ComboInput } from "@Input/ComboInput/ComboInput";
import "./SettingPopup.scss"; import "./SettingPopup.scss";
interface ISettingPopupProps { interface ISettingPopupProps {
} }
@@ -24,10 +27,42 @@ class SettingPopup extends Popup<ISettingPopupProps> {
} }
} }
class SettingPopupComponent extends Component<ISettingPopupProps> { @useSettingWithEvent("themes", "language")
class SettingPopupComponent extends Component<ISettingPopupProps & IMixinSettingProps> {
public render(): ReactNode { public render(): ReactNode {
return <Theme className="setting-popup"></Theme> return <Theme className="setting-popup">
<ComboInput
keyI18n="Language"
allOption={[
{ key: "EN_US", i18n: "EN_US" },
{ key: "ZH_CN", i18n: "ZH_CN" }
]}
value={{
key: this.props.setting?.language ?? "EN_US",
i18n: this.props.setting?.language ?? "EN_US"
}}
valueChange={(data) => {
this.props.setting?.setProps("language", data.key as any);
}}
/>
<ComboInput
keyI18n="Themes"
allOption={[
{ key: Themes.dark as any, i18n: "Themes.Dark" },
{ key: Themes.light as any, i18n: "Themes.Light" }
]}
value={{
key: this.props.setting?.themes ?? Themes.dark as any,
i18n: this.props.setting?.themes === Themes.dark ? "Themes.Dark" : "Themes.Light"
}}
valueChange={(data) => {
this.props.setting?.setProps("themes", parseInt(data.key));
}}
/>
</Theme>
} }
} }
+4
View File
@@ -1,6 +1,10 @@
const EN_US = { const EN_US = {
"Language": "Language",
"EN_US": "English (US)", "EN_US": "English (US)",
"ZH_CN": "Chinese (Simplified)", "ZH_CN": "Chinese (Simplified)",
"Themes": "Themes",
"Themes.Dark": "Dark",
"Themes.Light": "Light",
"Header.Bar.Title": "Living Together | Emulator", "Header.Bar.Title": "Living Together | Emulator",
"Header.Bar.Title.Info": "Group Behavior Research Emulator", "Header.Bar.Title.Info": "Group Behavior Research Emulator",
"Header.Bar.File.Name.Info": "{file} ({status})", "Header.Bar.File.Name.Info": "{file} ({status})",
+4
View File
@@ -1,6 +1,10 @@
const ZH_CN = { const ZH_CN = {
"Language": "语言",
"EN_US": "英语 (美国)", "EN_US": "英语 (美国)",
"ZH_CN": "中文 (简体)", "ZH_CN": "中文 (简体)",
"Themes": "主题",
"Themes.Dark": "黑暗",
"Themes.Light": "亮色",
"Header.Bar.Title": "群生共进 | 仿真器", "Header.Bar.Title": "群生共进 | 仿真器",
"Header.Bar.Title.Info": "群体行为研究仿真器", "Header.Bar.Title.Info": "群体行为研究仿真器",
"Header.Bar.File.Name.Info": "{file} ({status})", "Header.Bar.File.Name.Info": "{file} ({status})",