Skip to content

Commit

Permalink
Merge pull request #43 from ProbableTrain/SmoothField
Browse files Browse the repository at this point in the history
Smooth field
  • Loading branch information
ProbableTrain authored May 5, 2020
2 parents 5b3e2f8 + a6239b0 commit b46dae8
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 25 deletions.
94 changes: 83 additions & 11 deletions dist/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<body style="background-color:grey;">
<svg id="map-svg"></svg>
<div>
<canvas id="map-canvas"></canvas>
<canvas id="map-canvas"></canvas> <!-- Must match util.ts and style.css -->
<canvas id="img-canvas"></canvas>
</div>
<script src="bundle.js"></script>
Expand Down
1 change: 1 addition & 0 deletions dist/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ html, body {
overflow: hidden;
}

/* Must match util.ts and index.html */
#map-canvas {
position:fixed;
left:0;
Expand Down
12 changes: 7 additions & 5 deletions src/ts/impl/basis_field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ export abstract class BasisField {

abstract getTensor(point: Vector): Tensor;

getWeightedTensor(point: Vector): Tensor {
return this.getTensor(point).scale(this.getTensorWeight(point));
getWeightedTensor(point: Vector, smooth: boolean): Tensor {
return this.getTensor(point).scale(this.getTensorWeight(point, smooth));
}

setFolder(): void {
Expand All @@ -70,15 +70,17 @@ export abstract class BasisField {
folder.add(this._centre, 'x');
folder.add(this._centre, 'y');
folder.add(this, '_size');
folder.add(this, '_decay', 0, 50);
folder.add(this, '_decay', -50, 50);
}

/**
* Interpolates between (0 and 1)^decay
*/
protected getTensorWeight(point: Vector): number {
protected getTensorWeight(point: Vector, smooth: boolean): number {
const normDistanceToCentre = point.clone().sub(this._centre).length() / this._size;

if (smooth) {
return normDistanceToCentre ** -this._decay;
}
// Stop (** 0) turning weight into 1, filling screen even when outside 'size'
if (this._decay === 0 && normDistanceToCentre >= 1) {
return 0;
Expand Down
27 changes: 25 additions & 2 deletions src/ts/impl/tensor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,22 @@ export default class Tensor {
this._theta = this.calculateTheta();
}

static fromAngle(angle: number): Tensor {
return new Tensor(1, [Math.cos(angle * 4), Math.sin(angle * 4)]);
}

static fromVector(vector: Vector): Tensor {
const t1 = vector.x ** 2 - vector.y ** 2;
const t2 = 2 * vector.x * vector.y;
const t3 = t1 ** 2 - t2 ** 2;
const t4 = 2 * t1 * t2;
return new Tensor(1, [t3, t4]);
}

static get zero(): Tensor {
return new Tensor(0, [0, 0]);
}

get theta(): number {
if (this.oldTheta) {
this._theta = this.calculateTheta();
Expand All @@ -21,9 +37,16 @@ export default class Tensor {
return this._theta;
}

add(tensor: Tensor): Tensor {
add(tensor: Tensor, smooth: boolean): Tensor {
this.matrix = this.matrix.map((v, i) => v * this.r + tensor.matrix[i] * tensor.r);
this.r = 2;

if (smooth) {
this.r = Math.hypot(...this.matrix);
this.matrix = this.matrix.map(v => v / this.r);
} else {
this.r = 2;
}

this.oldTheta = true;
return this;
}
Expand Down
8 changes: 5 additions & 3 deletions src/ts/impl/tensor_field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export default class TensorField {
public river: Vector[] = [];
public ignoreRiver = false;

public smooth = false;

constructor(public noiseParams: NoiseParams) {
this.noise = new SimplexNoise();
}
Expand Down Expand Up @@ -79,16 +81,16 @@ export default class TensorField {
samplePoint(point: Vector): Tensor {
if (!this.onLand(point)) {
// Degenerate point
return new Tensor(0, [0,0]);
return Tensor.zero;
}

// Default field is a grid
if (this.basisFields.length === 0) {
return new Tensor(1, [0, 0]);
}

const tensorAcc = new Tensor(0, [0, 0]);
this.basisFields.forEach(field => tensorAcc.add(field.getWeightedTensor(point)));
const tensorAcc = Tensor.zero;
this.basisFields.forEach(field => tensorAcc.add(field.getWeightedTensor(point, this.smooth), this.smooth));

// Add rotational noise for parks - range -pi/2 to pi/2
if (this.parks.some(p => PolygonUtil.insidePolygon(point, p))) {
Expand Down
7 changes: 4 additions & 3 deletions src/ts/ui/tensor_field_gui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default class TensorFieldGUI extends TensorField {
};

this.guiFolder.add(tensorFieldGuiObj, 'reset');
this.guiFolder.add(this, 'smooth');
this.guiFolder.add(tensorFieldGuiObj, 'setRecommended');
this.guiFolder.add(tensorFieldGuiObj, 'addRadial');
this.guiFolder.add(tensorFieldGuiObj, 'addGrid');
Expand All @@ -52,7 +53,7 @@ export default class TensorFieldGUI extends TensorField {
addRadialRandom(): void {
const width = this.domainController.worldDimensions.x;
this.addRadial(this.randomLocation(),
Util.randomRange(width/10, width/5), // Size
Util.randomRange(width / 10, width / 5), // Size
Util.randomRange(50)); // Decay
}

Expand All @@ -63,9 +64,9 @@ export default class TensorFieldGUI extends TensorField {
private addGridAtLocation(location: Vector): void {
const width = this.domainController.worldDimensions.x;
this.addGrid(location,
Util.randomRange(width/4, width), // Size
Util.randomRange(width / 4, width), // Size
Util.randomRange(50), // Decay
Util.randomRange(Math.PI/2));
Util.randomRange(Math.PI / 2));
}

/**
Expand Down

0 comments on commit b46dae8

Please # to comment.