Add individuals gen function
This commit is contained in:
parent
1acc83e41c
commit
c44c10ad42
@ -37,6 +37,7 @@ interface IStatusEvent {
|
|||||||
rangeAttrChange: void;
|
rangeAttrChange: void;
|
||||||
labelAttrChange: void;
|
labelAttrChange: void;
|
||||||
groupAttrChange: void;
|
groupAttrChange: void;
|
||||||
|
individualChange: void;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Status extends Emitter<IStatusEvent> {
|
class Status extends Emitter<IStatusEvent> {
|
||||||
@ -74,6 +75,16 @@ class Status extends Emitter<IStatusEvent> {
|
|||||||
*/
|
*/
|
||||||
public focusLabel?: Label;
|
public focusLabel?: Label;
|
||||||
|
|
||||||
|
private drawtimer?: NodeJS.Timeout;
|
||||||
|
|
||||||
|
private delayDraw = () => {
|
||||||
|
this.drawtimer ? clearTimeout(this.drawtimer) : null;
|
||||||
|
this.drawtimer = setTimeout(() => {
|
||||||
|
this.model.draw();
|
||||||
|
this.drawtimer = undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@ -85,11 +96,11 @@ class Status extends Emitter<IStatusEvent> {
|
|||||||
this.model.on("labelChange", () => this.emit("labelChange"));
|
this.model.on("labelChange", () => this.emit("labelChange"));
|
||||||
|
|
||||||
// 对象变换时执行渲染,更新渲染器数据
|
// 对象变换时执行渲染,更新渲染器数据
|
||||||
this.on("objectChange", () => {
|
this.on("objectChange", this.delayDraw);
|
||||||
setTimeout(() => {
|
this.model.on("individualChange", this.delayDraw);
|
||||||
this.model.draw();
|
this.model.on("individualChange", () => {
|
||||||
|
this.emit("individualChange");
|
||||||
});
|
});
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bindRenderer(renderer: AbstractRenderer) {
|
public bindRenderer(renderer: AbstractRenderer) {
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { Individual } from "./Individual";
|
import { Individual } from "./Individual";
|
||||||
import { CtrlObject } from "./CtrlObject";
|
import { CtrlObject } from "./CtrlObject";
|
||||||
import type { Behavior } from "./Behavior";
|
import type { Behavior } from "./Behavior";
|
||||||
import type { Label } from "./Label";
|
import { Label } from "./Label";
|
||||||
|
import { Range } from "./Range";
|
||||||
|
|
||||||
enum GenMod {
|
enum GenMod {
|
||||||
Point = "p",
|
Point = "p",
|
||||||
@ -36,7 +37,123 @@ class Group extends CtrlObject {
|
|||||||
/**
|
/**
|
||||||
* 生成个数
|
* 生成个数
|
||||||
*/
|
*/
|
||||||
public genCount?: number = 0;
|
public genCount: number = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成错误信息
|
||||||
|
*/
|
||||||
|
public genErrorMessage?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成错误信息
|
||||||
|
*/
|
||||||
|
public genErrorMessageShowCount?: string;
|
||||||
|
|
||||||
|
private genInSingelRange(count: number, range: Range) {
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
let individual = new Individual(this);
|
||||||
|
individual.position[0] = range.position[0] + (Math.random() - .5) * 2 * range.radius[0];
|
||||||
|
individual.position[1] = range.position[1] + (Math.random() - .5) * 2 * range.radius[1];
|
||||||
|
individual.position[2] = range.position[2] + (Math.random() - .5) * 2 * range.radius[2];
|
||||||
|
this.add(individual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private genWithPointMod(): boolean {
|
||||||
|
for (let i = 0; i < this.genCount; i++) {
|
||||||
|
let individual = new Individual(this);
|
||||||
|
individual.position[0] = this.genPoint[0];
|
||||||
|
individual.position[1] = this.genPoint[1];
|
||||||
|
individual.position[2] = this.genPoint[2];
|
||||||
|
this.add(individual);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private genWithRangeMod(): boolean {
|
||||||
|
let rangeList: Range[] = [];
|
||||||
|
|
||||||
|
// 单一范围对象
|
||||||
|
if (this.genRange instanceof Range) {
|
||||||
|
rangeList = [this.genRange];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 多重范围对象
|
||||||
|
if (this.genRange instanceof Label) {
|
||||||
|
let objList: CtrlObject[] = this.model.getObjectByLabel(this.genRange);
|
||||||
|
rangeList = objList.filter((obj) => obj instanceof Range) as Range[]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单一范围生成
|
||||||
|
if (rangeList.length === 1) {
|
||||||
|
this.genInSingelRange(this.genCount, rangeList[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 多重范围
|
||||||
|
else if (rangeList.length > 1) {
|
||||||
|
let allVolume: number = 0;
|
||||||
|
let allGenCount: number = 0;
|
||||||
|
let genData: number[] = [];
|
||||||
|
|
||||||
|
// 计算体积
|
||||||
|
for (let i = 0; i < rangeList.length; i++) {
|
||||||
|
let volume =
|
||||||
|
rangeList[i].radius[0] *
|
||||||
|
rangeList[i].radius[1] *
|
||||||
|
rangeList[i].radius[2];
|
||||||
|
allVolume += volume;
|
||||||
|
genData.push(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按权重分配生成个数
|
||||||
|
for (let i = 0; i < genData.length; i++) {
|
||||||
|
const count = Math.floor((genData[i] / allVolume) * this.genCount) + 1;
|
||||||
|
allGenCount += count;
|
||||||
|
genData[i] = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按照溢出个数删除冗余个数
|
||||||
|
let morCount = allGenCount - this.genCount;
|
||||||
|
let safeCount = 0;
|
||||||
|
while (morCount > 0 && safeCount < 1000) {
|
||||||
|
safeCount ++;
|
||||||
|
let randomIndex = Math.floor(Math.random() * genData.length);
|
||||||
|
if (genData[randomIndex] > 0) {
|
||||||
|
genData[randomIndex] --;
|
||||||
|
morCount --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数据生成
|
||||||
|
for (let i = 0; i < rangeList.length; i++) {
|
||||||
|
this.genInSingelRange(genData[i], rangeList[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成个体
|
||||||
|
*/
|
||||||
|
public genIndividuals(): boolean {
|
||||||
|
let success = false;
|
||||||
|
switch (this.genMethod) {
|
||||||
|
case GenMod.Point:
|
||||||
|
success = this.genWithPointMod();
|
||||||
|
break;
|
||||||
|
case GenMod.Range:
|
||||||
|
success = this.genWithRangeMod();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (success) {
|
||||||
|
this.model.emit("individualChange", this);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建个体
|
* 创建个体
|
||||||
|
@ -17,6 +17,7 @@ type ModelEvent = {
|
|||||||
objectAdd: CtrlObject;
|
objectAdd: CtrlObject;
|
||||||
objectDelete: CtrlObject[];
|
objectDelete: CtrlObject[];
|
||||||
objectChange: CtrlObject[];
|
objectChange: CtrlObject[];
|
||||||
|
individualChange: Group;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,7 +116,7 @@ class GroupDetails extends Component<IGroupDetailsProps & IMixinStatusProps> {
|
|||||||
|
|
||||||
<AttrInput
|
<AttrInput
|
||||||
id={group.id} isNumber={true} step={1} keyI18n="Common.Attr.Key.Generation.Count"
|
id={group.id} isNumber={true} step={1} keyI18n="Common.Attr.Key.Generation.Count"
|
||||||
value={group.genCount} min={0} max={1000}
|
value={group.genCount} min={1} max={1000}
|
||||||
valueChange={(val) => {
|
valueChange={(val) => {
|
||||||
this.props.status?.changeGroupAttrib(group.id, "genCount", (val as any) / 1);
|
this.props.status?.changeGroupAttrib(group.id, "genCount", (val as any) / 1);
|
||||||
}}
|
}}
|
||||||
@ -130,7 +130,7 @@ class GroupDetails extends Component<IGroupDetailsProps & IMixinStatusProps> {
|
|||||||
keyI18n="Common.Attr.Key.Generation"
|
keyI18n="Common.Attr.Key.Generation"
|
||||||
onIconName="BuildDefinition" offIconName="BuildDefinition"
|
onIconName="BuildDefinition" offIconName="BuildDefinition"
|
||||||
valueChange={() => {
|
valueChange={() => {
|
||||||
console.log("gen");
|
group.genIndividuals();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user