algomin
Version:
Algomin - Viszualizing Distributed Algorithms
155 lines (132 loc) • 4.22 kB
JavaScript
import {BaseModel} from "./BaseModel";
import {Model} from "../Model";
/**
* Creates a random string
* @param length
* @returns {string}
*/
function generateRandomString(length) {
const possibleCharacters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let randomString = '';
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * possibleCharacters.length);
randomString += possibleCharacters[randomIndex];
}
return randomString;
}
export class Message extends BaseModel{
/**
* Static list containing all created Messages
* @type {[]}
*/
static messages = [];
/**
* When initialized, it sets the death_time to creation_time + speed.
* Adds itself to the static messages list
* @param source Source Shape
* @param target Target Shape
* @param speed Speed in ms
* @param label Label
* @param creation_time Creation Time
*/
constructor(source, target, speed, label, creation_time) {
super(generateRandomString(), source._x, source._y, 3, 50, label, creation_time, creation_time + parseInt(speed), "message");
this._source = source;
this._target = target;
this._speed = speed;
Message.messages.push(this);
}
get source(){
return this._source;
}
get target(){
return this._target;
}
get speed(){
return this._speed;
}
/**
* Returns the angle between the the source and target Shape
* @returns {number}
*/
get angle(){
return Message.getAngleBetweenTwoPoints(
this.source.middleX,
this.source.middleY,
this.target.middleX,
this.target.middleY
)
}
/**
* Reverse calculates the angle for the label within, so it stays horizontal
* @returns {number}
*/
get labelAngle(){
return 360 - this.angle;
}
/**
* Calculates the current x position by using the distance and current runtime of the Model
* @returns {null|number}
*/
get x(){
if(this.creationTime < Model.time){
const distance = this.target.middleX - this.source.middleX;
let percentage_distance = (Model.time - this.creationTime) / this.speed;
if(percentage_distance > 1){
percentage_distance = 1;
}
let current_x = parseInt(this.source.middleX) + (percentage_distance * distance);
current_x = current_x - (this.w / 2);
return current_x;
}
return this._x;
}
/**
* Calculates the current y position by using the distance and current runtime of the Model
* @returns {null|number}
*/
get y(){
if(this.isVisible()){
const distance = this.target.middleY - this.source.middleY;
let percentage_distance = (Model.time - this.creationTime) / this.speed;
if(percentage_distance > 1){
percentage_distance = 1;
}
let current_y = this.source.middleY + (percentage_distance * distance);
current_y = current_y - (this._h / 2);
return current_y;
}
return this._y;
}
set x(value){
this._x = value;
}
set y(value){
this._y = value;
}
/**
* Clears all Messages
*/
static clearMessages(){
Message.messages = [];
}
/**
* Returns the angle of two points
* @param ax x of object 1
* @param ay y of object 1
* @param bx x of object 2
* @param by y of object 2
* @returns {number}
*/
static getAngleBetweenTwoPoints(ax, ay, bx, by){
const dx = bx - ax;
const dy = by - ay;
let angleRadians = Math.atan2(dy, dx);
let angleDegrees = (angleRadians * 180) / Math.PI;
angleDegrees += 90;
if (angleDegrees < 0) {
angleDegrees += 360;
}
return angleDegrees
}
}