Add math function into individual and group
This commit is contained in:
parent
f999fc1268
commit
ff4c85f589
@ -6,18 +6,75 @@ import { Individual } from "./Individual";
|
|||||||
class Group {
|
class Group {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 所有成员
|
* 所有个体
|
||||||
*/
|
*/
|
||||||
public individuals: Individual[] = [];
|
public individuals: Set<Individual> = new Set();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加一个成员
|
* 创建个体
|
||||||
|
* @param count 创建数量
|
||||||
*/
|
*/
|
||||||
public add(count: number = 1) {
|
public new(count: number = 1): this {
|
||||||
for (let i = 0; i < count; i++) {
|
for (let i = 0; i < count; i++) {
|
||||||
this.individuals.push(new Individual(this));
|
this.individuals.add(new Individual(this));
|
||||||
}
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加个体
|
||||||
|
* @param individual 个体
|
||||||
|
*/
|
||||||
|
public add(individual: Individual[] | Individual): this {
|
||||||
|
if (Array.isArray(individual)) {
|
||||||
|
for (let i = 0; i < individual.length; i++) {
|
||||||
|
this.individuals.add(individual[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.individuals.add(individual);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除成员
|
||||||
|
* @param individual 需要移除的个体
|
||||||
|
*/
|
||||||
|
public remove(individual: Individual[] | Individual): this {
|
||||||
|
if (Array.isArray(individual)) {
|
||||||
|
for (let i = 0; i < individual.length; i++) {
|
||||||
|
this.individuals.delete(individual[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.individuals.delete(individual);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过距离获取个体
|
||||||
|
* 此函数将排除传入对象
|
||||||
|
* @param position 观测位置
|
||||||
|
* @param distance 距离
|
||||||
|
* @param excludeSelf 是否排除自身
|
||||||
|
*/
|
||||||
|
public getIndividualsByDistance(
|
||||||
|
position: Individual | number[], distance: number, excludeSelf?: boolean
|
||||||
|
): Individual[] {
|
||||||
|
const result: Individual[] = [];
|
||||||
|
this.individuals.forEach(((individual) => {
|
||||||
|
|
||||||
|
// 排除自身
|
||||||
|
if (individual === position && excludeSelf) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (individual.distanceTo(position) < distance) {
|
||||||
|
result.push(individual);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Group;
|
export default Group;
|
||||||
|
@ -5,6 +5,47 @@ import type { Group } from "./Group";
|
|||||||
*/
|
*/
|
||||||
class Individual {
|
class Individual {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算向量长度
|
||||||
|
* @param x x 坐标 | 向量
|
||||||
|
* @param y y 坐标
|
||||||
|
* @param z z 坐标
|
||||||
|
*/
|
||||||
|
public static vectorLength(x: number[]): number;
|
||||||
|
public static vectorLength(x: number, y: number, z: number): number;
|
||||||
|
public static vectorLength(x: number | number[], y?: number, z?: number): number {
|
||||||
|
if (Array.isArray(x)) {
|
||||||
|
return ((x[0] ?? 0)**2 + (x[1] ?? 0)**2 + (x[2] ?? 0)**2)**.5;
|
||||||
|
} else {
|
||||||
|
return ((x ?? 0)**2 + (y ?? 0)**2 + (z ?? 0)**2)**.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向量归一化
|
||||||
|
* @param x x 坐标 | 向量
|
||||||
|
* @param y y 坐标
|
||||||
|
* @param z z 坐标
|
||||||
|
*/
|
||||||
|
public static vectorNormalize(x: number[]): [number, number, number];
|
||||||
|
public static vectorNormalize(x: number, y: number, z: number): [number, number, number];
|
||||||
|
public static vectorNormalize(x: number | number[], y?: number, z?: number): [number, number, number] {
|
||||||
|
let length = Individual.vectorLength(x as number, y as number, z as number);
|
||||||
|
if (Array.isArray(x)) {
|
||||||
|
return [
|
||||||
|
(x[0] ?? 0) / length,
|
||||||
|
(x[1] ?? 0) / length,
|
||||||
|
(x[2] ?? 0) / length
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
(x ?? 0) / length,
|
||||||
|
(y ?? 0) / length,
|
||||||
|
(z ?? 0) / length
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 坐标
|
* 坐标
|
||||||
*/
|
*/
|
||||||
@ -21,6 +62,52 @@ class Individual {
|
|||||||
public constructor(group: Group) {
|
public constructor(group: Group) {
|
||||||
this.group = group;
|
this.group = group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 死亡
|
||||||
|
*/
|
||||||
|
public die(): this {
|
||||||
|
this.group.remove(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转移到新群体
|
||||||
|
* @param newGroup 新群体
|
||||||
|
*/
|
||||||
|
public transfer(newGroup: Group): this {
|
||||||
|
this.group.remove(this);
|
||||||
|
newGroup.add(this);
|
||||||
|
this.group = newGroup;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算从此个体到目标位置的向量
|
||||||
|
*/
|
||||||
|
public vectorTo(position: Individual | number[]): [number, number, number] {
|
||||||
|
if (position instanceof Individual) {
|
||||||
|
return [
|
||||||
|
position.position[0] - this.position[0],
|
||||||
|
position.position[1] - this.position[1],
|
||||||
|
position.position[2] - this.position[2]
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
(position[0] ?? 0) - this.position[0],
|
||||||
|
(position[1] ?? 0) - this.position[1],
|
||||||
|
(position[2] ?? 0) - this.position[2]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算与目标位置距离
|
||||||
|
* @param position 目标位置
|
||||||
|
*/
|
||||||
|
public distanceTo(position: Individual | number[]): number {
|
||||||
|
return Individual.vectorLength(this.vectorTo(position));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Individual;
|
export default Individual;
|
||||||
|
Loading…
Reference in New Issue
Block a user