Add individuals gen function
This commit is contained in:
parent
1acc83e41c
commit
c44c10ad42
@ -37,6 +37,7 @@ interface IStatusEvent {
|
||||
rangeAttrChange: void;
|
||||
labelAttrChange: void;
|
||||
groupAttrChange: void;
|
||||
individualChange: void;
|
||||
}
|
||||
|
||||
class Status extends Emitter<IStatusEvent> {
|
||||
@ -74,6 +75,16 @@ class Status extends Emitter<IStatusEvent> {
|
||||
*/
|
||||
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() {
|
||||
super();
|
||||
|
||||
@ -85,11 +96,11 @@ class Status extends Emitter<IStatusEvent> {
|
||||
this.model.on("labelChange", () => this.emit("labelChange"));
|
||||
|
||||
// 对象变换时执行渲染,更新渲染器数据
|
||||
this.on("objectChange", () => {
|
||||
setTimeout(() => {
|
||||
this.model.draw();
|
||||
this.on("objectChange", this.delayDraw);
|
||||
this.model.on("individualChange", this.delayDraw);
|
||||
this.model.on("individualChange", () => {
|
||||
this.emit("individualChange");
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
public bindRenderer(renderer: AbstractRenderer) {
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Individual } from "./Individual";
|
||||
import { CtrlObject } from "./CtrlObject";
|
||||
import type { Behavior } from "./Behavior";
|
||||
import type { Label } from "./Label";
|
||||
import { Label } from "./Label";
|
||||
import { Range } from "./Range";
|
||||
|
||||
enum GenMod {
|
||||
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;
|
||||
objectDelete: CtrlObject[];
|
||||
objectChange: CtrlObject[];
|
||||
individualChange: Group;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -116,7 +116,7 @@ class GroupDetails extends Component<IGroupDetailsProps & IMixinStatusProps> {
|
||||
|
||||
<AttrInput
|
||||
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) => {
|
||||
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"
|
||||
onIconName="BuildDefinition" offIconName="BuildDefinition"
|
||||
valueChange={() => {
|
||||
console.log("gen");
|
||||
group.genIndividuals();
|
||||
}}
|
||||
/>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user