2
0

prepared library publishing

This commit is contained in:
2018-08-31 15:05:12 +02:00
parent da36b71b2c
commit 04b049f39f
24 changed files with 82 additions and 175 deletions

View File

@@ -18,18 +18,16 @@ import { ConfigForm } from './forms/config.form';
import { Component, OnInit, HostListener } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
// import { Moment } from 'moment';
import * as moment from 'moment';
import 'moment/min/locales';
import { environment as env } from '../environments/environment';
import { Param } from './models/param.model';
import { Config } from './models/config.model';
import { CanvasService } from './services/canvas.service';
import { HistoryService } from './services/history.service';
import { Graph } from './models/graph.model';
import { GraphService } from './services/graph.service';
import { AnimationService } from './services/animation.service';
import { Param } from './../../projects/nls-guilloche/src/lib/models/param.model';
import { Config } from './../../projects/nls-guilloche/src/lib/models/config.model';
import { Graph } from './../../projects/nls-guilloche/src/lib/models/graph.model';
import { NlsCanvasService } from './../../projects/nls-guilloche/src/lib/services/canvas.service';
import { NlsHistoryService } from './../../projects/nls-guilloche/src/lib/services/history.service';
import { NlsGraphService } from './../../projects/nls-guilloche/src/lib/services/graph.service';
@Component({
selector: 'app-root',
@@ -48,9 +46,9 @@ export class AppComponent implements OnInit {
public animationActive: boolean;
constructor(
private canvasService: CanvasService,
private historyService: HistoryService,
private graphService: GraphService,
private canvasService: NlsCanvasService,
private historyService: NlsHistoryService,
private graphService: NlsGraphService,
) {
moment.locale('de');

View File

@@ -22,18 +22,18 @@ import { MomentModule } from 'ngx-moment';
import { AppComponent } from './app.component';
import { GraphsComponent } from './components/graphs.component';
import { GuillocheDirective } from './directives/guilloche.directive';
import { CanvasService } from './services/canvas.service';
import { HistoryService } from './services/history.service';
import { AnimationService } from './services/animation.service';
import { MathService } from './services/math.service';
import { GraphService } from './services/graph.service';
import { NlsGuillocheDirective } from './../../projects/nls-guilloche/src/lib/directives/guilloche.directive';
import { NlsCanvasService } from './../../projects/nls-guilloche/src/lib/services/canvas.service';
import { NlsHistoryService } from './../../projects/nls-guilloche/src/lib/services/history.service';
import { NlsAnimationService } from './../../projects/nls-guilloche/src/lib/services/animation.service';
import { NlsMathService } from './../../projects/nls-guilloche/src/lib/services/math.service';
import { NlsGraphService } from './../../projects/nls-guilloche/src/lib/services/graph.service';
@NgModule({
declarations: [
AppComponent,
GraphsComponent,
GuillocheDirective
NlsGuillocheDirective
],
imports: [
BrowserModule,
@@ -43,11 +43,11 @@ import { GraphService } from './services/graph.service';
MomentModule,
],
providers: [
CanvasService,
HistoryService,
AnimationService,
MathService,
GraphService,
NlsCanvasService,
NlsHistoryService,
NlsAnimationService,
NlsMathService,
NlsGraphService,
],
bootstrap: [AppComponent]
})

View File

@@ -1,6 +1,6 @@
<svg #svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"
version="1.1" shape-rendering="geometricPrecision">
<g guilloche [graph]="graphs[0]" [matrix]="matrix" [config]="config" [animate]="true" (guillocheChange)="prepareGuillocheExport($event)"></g>
<g guilloche [graph]="graphs[1]" [matrix]="matrix" [config]="config" [animate]="true" (guillocheChange)="prepareGuillocheExport($event)"></g>
<!-- <g guilloche *ngFor="let graph of graphs" [graph]="graph" [matrix]="matrix" [config]="config" [animate]="true" (guillocheChange)="prepareGuillocheExport($event)"></g> -->
<g nlsGuilloche [graph]="graphs[0]" [matrix]="matrix" [config]="config" [animate]="true"></g>
<g nlsGuilloche [graph]="graphs[1]" [matrix]="matrix" [config]="config" [animate]="true"></g>
<!-- <g nlsGuilloche *ngFor="let graph of graphs" [graph]="graph" [matrix]="matrix" [config]="config" [animate]="true"></g> -->
</svg>

Before

Width:  |  Height:  |  Size: 597 B

After

Width:  |  Height:  |  Size: 453 B

View File

@@ -14,9 +14,9 @@
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
svg {
// opacity: 0.4;
}
// svg {
// // opacity: 0.4;
// }
// svg {
// stroke-dasharray: 1000px;

View File

@@ -22,14 +22,13 @@ import * as Random from 'd3-random';
import * as Drag from 'd3-drag';
import { environment as env } from '../../environments/environment';
import { CanvasService } from './../services/canvas.service';
import { HistoryService } from './../services/history.service';
import { AnimationService } from '../services/animation.service';
import { MathService } from '../services/math.service';
import { GuillocheDirective } from './../directives/guilloche.directive';
import { Graph } from '../models/graph.model';
import { Point } from '../models/point.model';
import { GraphService } from '../services/graph.service';
import { Graph } from './../../../projects/nls-guilloche/src/lib/models/graph.model';
import { Point } from './../../../projects/nls-guilloche/src/lib/models/point.model';
import { NlsCanvasService } from './../../../projects/nls-guilloche/src/lib/services/canvas.service';
import { NlsHistoryService } from './../../../projects/nls-guilloche/src/lib/services/history.service';
import { NlsMathService } from './../../../projects/nls-guilloche/src/lib/services/math.service';
import { NlsGuillocheDirective } from './../../../projects/nls-guilloche/src/lib/directives/guilloche.directive';
import { NlsGraphService } from './../../../projects/nls-guilloche/src/lib/services/graph.service';
@Component({
selector: 'app-graphs',
@@ -63,11 +62,10 @@ export class GraphsComponent implements OnChanges, OnInit {
}
constructor(
private canvasService: CanvasService,
private historyService: HistoryService,
private animationService: AnimationService,
private math: MathService,
private graphService: GraphService
private canvasService: NlsCanvasService,
private historyService: NlsHistoryService,
private math: NlsMathService,
private graphService: NlsGraphService
) {
this.genLoadedAllGraphs = this.countLoadedGraphs();
this.timer = interval(500);

View File

@@ -1,224 +0,0 @@
/**
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { ElementRef, HostListener, Output, EventEmitter, Input, Directive, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
import * as Selection from 'd3-selection';
import * as Shape from 'd3-shape';
import * as Random from 'd3-random';
import * as Drag from 'd3-drag';
import * as Ease from 'd3-ease';
import * as Timer from 'd3-timer';
import { environment as env } from './../../environments/environment';
import { Config } from './../models/config.model';
import { Graph } from './../models/graph.model';
import { Point } from './../models/point.model';
import { Param } from './../models/param.model';
import { CanvasService } from './../services/canvas.service';
import { MathService } from './../services/math.service';
import { GraphService } from '../services/graph.service';
import { AnimationService } from './../services/animation.service';
const ANIMATION_INTERVAL = 60;
@Directive({
selector: '[guilloche]'
})
export class GuillocheDirective implements OnChanges, OnDestroy {
private canvas: any;
private group: any;
private bounce: any | null;
private bounces: any | null;
private initialNodes: any;
private initialCurve: any;
private animationInterval: any;
private medianPoint: Point;
private medianIndex: number;
private pathElements: any;
@Input() graph: Graph;
@Input() matrix: any;
@Input() config: any;
@Input() animate: boolean;
@Output() guillocheChange = new EventEmitter();
constructor(
private canvasService: CanvasService,
private el: ElementRef,
private math: MathService,
private graphService: GraphService,
private animationService: AnimationService
) {
}
ngOnDestroy() {
this.group.selectAll('*').remove();
}
ngOnChanges(changes: SimpleChanges) {
this.group = Selection.select(this.el.nativeElement);
this.canvas = Selection.select(this.canvasService.get);
// @todo modify graph here instead of in graphs.component.ts
this.initialNodes = this.graph.nodes.slice();
this.initialCurve = [
this.graph.start.point,
this.graph.start.direction,
...this.graph.nodes.slice(),
this.graph.end.direction,
this.graph.end.point
];
this.medianPoint = this.math.medianOfCurve(this.initialCurve);
this.medianIndex = this.math.medianIndex(this.initialCurve);
if (this.graphService.isAnimated) {
this.graph.nodes = this.graph.nodes.slice().map((node, i) => {
return {
x: node.x,
y: node.y,
// ascent: Math.round(Math.random() * 100) / 100
ascent: this.medianPoint.ascent + i * 0.5
};
});
this.bounces = this.initialNodes.map(node => {
const bounceAmplitude = Math.round(Math.random() * 150);
return this.math.bounce(bounceAmplitude, 3);
});
let i = 0;
this.animationInterval = setInterval(() => {
// this.animateGraph();
this.animateGraph(i++ % 1000 / 10000);
}, ANIMATION_INTERVAL);
} else {
if (this.animationInterval) {
this.bounce = null;
clearInterval(this.animationInterval);
// return;
}
}
this.group.selectAll('*').remove();
this.pathElements = [];
const graphs = this.spreadLines([
this.graph.start.point,
this.graph.start.direction,
...this.graph.nodes,
this.graph.end.direction,
this.graph.end.point,
]).forEach((points, index) => this.drawGraph(points));
this.guillocheChanged();
}
private animateGraph(x) {
const graphs = this.spreadLines([
this.graph.start.point,
this.graph.start.direction,
...this.graph.nodes.map((point, i) => {
const ascent = point.ascent * Math.sin(Math.PI * x);
return this.graphService.shiftPoint(point, ascent, this.bounces[i].next().value);
}),
this.graph.end.direction,
this.graph.end.point,
]);
graphs.forEach((points, i) => this.updateGraph(points, i));
}
private spreadLines(points: Point[]) {
const shiftedMedians = [];
const genshiftedMedians = this.graphService.spreadOrthogonal(this.medianPoint, this.config.spread.spacing);
for (let i = 0; i < this.config.spread.amount; i++) {
shiftedMedians.push(genshiftedMedians.next().value);
}
return shiftedMedians.map(median => {
const shiftedPoints = points.slice();
shiftedPoints.splice(this.medianIndex, 1, median);
return shiftedPoints;
});
}
private updateGraph(points: Point[], index: number): void {
this.pathElements[index]
.attr('d', Shape.line()
.x(p => p.x)
.y(p => p.y)
.curve(Shape.curveBasis)(points));
// if (env.debug) {
// this.group.selectAll('circle').remove();
// this.group.selectAll('text').remove();
// // this.debugGraph(points);
// }
}
private drawGraph(points: Point[]): void {
this.group
.attr('stroke', this.graph.color)
.attr('stroke-width', this.graph.stroke)
.attr('fill', 'none');
this.pathElements.push(
this.group.append('path')
.attr('d', Shape.line()
.x(p => p.x)
.y(p => p.y)
.curve(Shape.curveBasis)(points)));
if (env.debug) {
this.debugGraph(points);
}
}
public guillocheChanged() {
this.guillocheChange.emit(this.el.nativeElement);
}
private debugGraph(points: Point[]) {
points.forEach((point, index) => {
const circle = this.group.append('g');
circle.append('circle')
.attr('cx', point.x)
.attr('cy', point.y)
.attr('r', 3)
.attr('fill-opacity', 0.6)
.attr('fill', this.graph.color);
circle.append('text')
.attr('x', point.x)
.attr('y', point.y)
.attr('dx', 8)
.attr('dy', 15)
.attr('fill', this.graph.color)
.text(index);
});
}
private debugBounce(point: Point): void {
if (env.debug) {
this.group.append('circle')
.attr('cx', point.x)
.attr('cy', point.y)
.attr('r', 2)
.attr('fill-opacity', 0.4)
.attr('fill', 'darkgray');
}
}
}

View File

@@ -1,37 +0,0 @@
/**
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
export interface Config {
width: number;
height: number;
start: {
x: number;
y: number;
color: string;
};
end: {
x: number;
y: number;
color: string;
};
vectors: {
spacing: number
};
spread: {
amount: number;
spacing: number
};
}

View File

@@ -1,34 +0,0 @@
/**
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { Point } from './point.model';
export interface Graph {
id: string;
color: string; // can be set in enviroment
start: {
point: Point;
direction?: Point;
vector: number; // degree between 0 and 360
};
end: {
point: Point;
direction?: Point;
vector: number; // degree between 0 and 360
};
stroke: number; // stroke width
nodes?: Point[]; // orientation points
}

View File

@@ -1,33 +0,0 @@
/**
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
export interface Param {
colors: {
start: string,
end: string
};
points: number;
margin: {
x: number,
y: number
};
spread: number;
space: number;
stroke?: {
width: number;
};
showGrid?: boolean;
}

View File

@@ -1,22 +0,0 @@
/**
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
export interface Point {
x: number;
y: number;
color?: string;
ascent?: number;
}

View File

@@ -1,60 +0,0 @@
/**
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { Inject, Injectable, Optional, ViewChild } from '@angular/core';
import { interval, Observable } from 'rxjs';
import * as Selection from 'd3-selection';
import { Graph } from '../models/graph.model';
import { MathService } from './math.service';
import { HistoryService } from './history.service';
@Injectable()
export class AnimationService {
public graphs: Graph[];
public speed: number;
public range: number;
// public genAnimation: any;
// private timer: Observable<number>;
// private subscribtion: any;
constructor(
private math: MathService,
private historyService: HistoryService,
) {
}
// public animate(initialGraphs: Graph[]) {
public animate(initialGraph: Graph) {
// const newGraphs = initialGraphs.slice();
// return newGraphs.map(graph => {
const newGraph = Object.assign({}, initialGraph);
const indexMiddle = Math.floor(newGraph.nodes.length * 0.5);
const pointMiddle = newGraph.nodes[indexMiddle];
newGraph.nodes.splice(indexMiddle, 1, {
x: pointMiddle.x - 2,
y: pointMiddle.y + 2,
});
return newGraph;
// });
}
}

View File

@@ -1,54 +0,0 @@
/**
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core';
import * as Selection from 'd3-selection';
@Injectable()
export class CanvasService {
private renderer: Renderer2;
public canvas: any;
constructor(
private rendererFactory: RendererFactory2
) {
this.renderer = rendererFactory.createRenderer(null, null);
}
public get get() {
return this.canvas;
}
public set(el) {
this.canvas = el;
}
public adjustToWindow() {
if (this.canvas) {
this.renderer.setStyle(
this.canvas,
'width',
window.innerWidth
);
this.renderer.setStyle(
this.canvas,
'height',
window.innerHeight
);
}
}
}

View File

@@ -1,75 +0,0 @@
import { Validators } from '@angular/forms';
/**
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core';
import * as Selection from 'd3-selection';
import { MathService } from './math.service';
import { Graph } from './../models/graph.model';
import { Point } from './../models/point.model';
@Injectable()
export class GraphService {
private graphs: Graph[];
private animation: boolean | null;
constructor(
private math: MathService
) {}
public get() {
return this.graphs;
}
public set(newGraphs: Graph[]) {
this.graphs = newGraphs;
}
public get isAnimated() {
return this.animation;
}
public startAnimation() {
this.animation = true;
}
public stopAnimation() {
this.animation = false;
}
public *spreadOrthogonal(start: Point, spacing: number) {
const sign = this.math.flipSign();
let currentPoint = start;
let i = 0;
while (true) {
const currentSpacing = sign.next().value * spacing * i;
currentPoint = this.shiftPoint(currentPoint, start.ascent, currentSpacing);
yield currentPoint;
i++;
}
}
public shiftPoint(point: Point, radians: number, spacing: number): Point {
return {
x: Math.sin(radians * Math.PI) * spacing + point.x,
y: Math.cos(radians * Math.PI) * spacing + point.y
};
}
}

View File

@@ -1,48 +0,0 @@
/**
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { Inject, Injectable, Optional, ViewChild } from '@angular/core';
import * as Selection from 'd3-selection';
import { Graph } from '../models/graph.model';
@Injectable()
export class HistoryService {
public history: any[];
constructor() {
this.history = [];
}
public save(graphs: Graph[], config) {
this.history.push({
date: new Date(),
graphs: graphs,
config: config,
hash: this.hash(graphs)
});
}
public hash(graphs) {
return btoa(JSON.stringify(graphs));
}
public list() {
return this.history;
}
}

View File

@@ -1,160 +0,0 @@
/**
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { Inject, Injectable } from '@angular/core';
import * as Selection from 'd3-selection';
import * as Random from 'd3-random';
import { Point } from './../models/point.model';
import { Graph } from './../models/graph.model';
@Injectable()
export class MathService {
/**
* Calculate distance between to points with coordinates.
* @param a
* @param b
*/
public Δ(a: Point, b: Point) {
return Math.pow(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2), 0.5);
}
public getClosestCenter(point: Point, matrix: any) {
if (this.Δ(point, matrix.start) < this.Δ(point, matrix.end)) {
return matrix.start;
} else {
return matrix.end;
}
}
public getFarestCenter(point: Point, matrix: any) {
if (this.Δ(point, matrix.start) > this.Δ(point, matrix.end)) {
return matrix.start;
} else {
return matrix.end;
}
}
public randomPoint(matrix: any, overlap: number) {
const x = {
min: matrix.center.x - matrix.width * overlap,
max: matrix.center.x + matrix.width * overlap
};
const y = {
min: matrix.center.y - matrix.height * overlap,
max: matrix.center.y + matrix.height * overlap
};
return {
x: Random.randomUniform(x.min, x.max)(),
y: Random.randomUniform(y.min, y.max)()
};
}
public centerOfArea(width, height): Point {
return {
x: width * 0.5,
y: height * 0.5
};
}
public centerOfPoints(p1: Point, p2: Point) {
return {
x: (p1.x + p2.x) * 0.5,
y: (p1.y + p2.y) * 0.5
};
}
public centerOfCurve(curve: Point[]) {
const genMedian = this.medianPoint(curve);
const p1 = genMedian.next().value;
const p2 = genMedian.next().value;
const radians = this.angleRadians(p1, p2);
return Object.assign(this.centerOfPoints(p1, p2), { ascent: radians });
}
public medianOfCurve(curve: Point[]) {
const genMedian = this.medianPoint(curve);
const p1 = genMedian.next().value;
const p2 = genMedian.next().value;
const p3 = genMedian.next().value;
const radians = this.angleRadians(p2, p3);
// const radians = Math.round(Math.random() * 10000) / 1000;
// @todo if nodes are less than 5 error occures
return Object.assign(p1, { ascent: radians });
}
public angleRadians(p1: Point, p2: Point) {
return Math.atan2(p2.y - p1.y, p2.x - p1.x);
}
public angleDegree(p1: Point, p2: Point) {
return this.angleRadians(p1, p2) * 180 / Math.PI;
}
public medianIndex(list: any): number {
return Math.floor(list.length * 0.5);
}
public *medianPoint(points: Point[]) {
let index: number;
const list: Point[] = points.slice();
while (list) {
index = this.medianIndex(points);
yield list[index];
list.splice(index, 1);
}
}
/**
* Generator for sine bounce
*
* @param start 0 indicates to initiate with positive numbers, 1 indicates to
* start with negative numbers first
* @param amplitude default to 1 indicates the amplitude in positive as well
* in negative range
* @param decimals amount of decimal places
*/
public *bounce(
amplitude: number = 1,
decimals: number = 1,
start: number = 0
) {
const power = Math.pow(10, decimals);
const step = 2 / (power);
let index = 0;
while (true) {
const radians = Math.PI * step * index + start;
yield Math.round((Math.sin(radians) * amplitude) * power) / power;
index++;
}
}
public *flipSign(startPositive: boolean = true) {
let sign = startPositive ? 1 : -1;
while (true) {
yield sign = sign * (-1);
}
}
}