Skip to content

Instantly share code, notes, and snippets.

@syronz
Created September 24, 2020 11:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save syronz/3dc192ce7d72abbaf9be15458d251a7e to your computer and use it in GitHub Desktop.
Save syronz/3dc192ce7d72abbaf9be15458d251a7e to your computer and use it in GitHub Desktop.
map generator (voronoi diagram)
<!doctype html>
<html>
<head>
<style>
canvas{
position: absolute;
}
</style>
<script type="text/javascript" src="script.js"></script>
<script>
/*--------------------------------------- Data structure
ADT
Line: x=R, y=R, m=R [x and y are the point and m is gradient]
Dot: x=R, y=R, borders:*[] [x and y are coordinates and borders is array of pointer to border]
Border: x0=R, y0=R, x1=R, y1=R, Point1=*, Point2=* [x0 and y0 are the first point coordinate]
Point[] = {x:width coordinate, y:height coordinate, lines[]:node of lines, borders[]:node of borders, dist[]: distance to other points}
line[] = {x:width of point coordinate, y:height of poinr coordinate, m:gradiant of line}
border[] = {}
LineFormul = [Ax + By + C = 0] , {A,B,C}
--------------------------------------------------------*/
/*--------------------------------------- Global Functions & Constance
* dsh(): costomize console.log()
* p2(a): return a*a
* points[]: for hold all points of map
* borders[]: for hold all borders of map
*--------------------------------------------------------------------*/
var SNAP = 0.000001;
function dsh(){
if(arguments.length > 1)
console.log(arguments);
else
console.log(arguments[0]);
}
function p2(a){
return a*a;
}
function snap(a){
if(Math.abs(a) <= SNAP)
return 0;
return a;
}
function floor(n){
var m = n / SNAP;
m = Math.round(m);
return m*SNAP;
}
function deleteBorderByIndex(i){
for(var j = 0; j < borders.length; j++){
if(borders[j].i == i)
break;
}
borders.splice(j,1);
}
points = [];
borders = [];
window.addEventListener('load',windowLoaded,false);
var W = 550;
var H = 550;
var theCanvas = null;
var context = null;
var mapSync = null;
function windowLoaded(){
theCanvas = document.getElementById("map" );
context = theCanvas.getContext("2d" );
getMap();
cordinateCanvas = document.getElementById("cordinate" );
cordinateCanvas.addEventListener('mousemove', function(evt) {
var mousePos = getMousePos(cordinateCanvas, evt);
var message = ' ' + mousePos.x + ',' + mousePos.y;
writeMessage(cordinateCanvas, message);
}, false);
}
function canvasApp(v){
points = [];
borders = [];
context.canvas.width = W;
context.canvas.height = H;
var mouseX;
var mouseY;
context.fillStyle = "#555555" ;
context.clearRect(0, 0, W,H);
context.strokeRect(0,0, W,H);
var row = v.length;
var col = v[0].length;
var cellWidth = W/row;
var cellHeight = H/col;
for(var i=0;i<row;i++){
for(var j=0;j<col;j++){
if(v[i][j] == 1){
context.beginPath();
context.arc(cellWidth*j + cellWidth/2, cellHeight*i + cellHeight/2, 10, 0, 2 * Math.PI, false);
context.fillStyle = '#31BF6F';
points.push(new Point(cellWidth*j + cellWidth/2,cellHeight*i + cellHeight/2));
// context.fill();
}
}
}
var pointsCount = points.length;
var arrDis = [];
for(var i=0; i<pointsCount; i++){
arrDis[i] = [];
for(var j=0; j<pointsCount; j++){
disCal = Math.sqrt( p2(points[i].x - points[j].x) + p2(points[i].y - points[j].y) );
arrDis[i][j] = disCal;
points[i].setDis(points[j],disCal);
}
}
dsh(points.length);
for(var i=0; i<pointsCount; i++){
points[i].i = i;
points[i].sortDis();
}
context.fillStyle = '#DDDDDD';
for (var i in points){
context.beginPath();
context.font = '12pt Calibri';
var margin = i>9?8:4
context.fillText(i, points[i].x - margin,points[i].y + 5);
context.fill();
}
/*---------------------------------- START Maping ----------------*/
var countMain = points.length;
var count = countMain;
for(var i =0; i< count; i++){
var pDot = points[i];
for(var l = 1; l<countMain; l++){
pNei = pDot.findNeighbor(l);
pDot.createPerpendicular(pNei);
}
pDot.pruningExtraBorder();
}
/*-------------------------------------START sandBox -------------------*/
// borders[0] = new Border(points[0],points[10]);
// borders[1] = new Border(points[8],points[3]);
// borders[2] = new Border(points[1],points[9]);
// var borders[1] = new Border(points[0].x,points[0].y,points[1].x,points[1].y);
// borders[0].show('pink');
// borders[1].show('red');
// borders[2].show('#4CAF50');
// points[5].createPerpendicular(points[4]);
// points[5].createPerpendicular(points[6]);
// points[5].createPerpendicular(points[3]);
// points[5].createPerpendicular(points[7]);
// points[5].createPerpendicular(points[13]);
// points[5].createPerpendicular(points[19]);
// points[5].createPerpendicular(points[26]);
// points[5].createPerpendicular(points[25]);
// points[5].pruningExtraBorder();
// points[5].showShape();
// dsh(points[6].isTargetOpen(borders[4].returnMiddle(),true));
// points[7].createPerpendicular(points[10]);
// deleteBorderByIndex(69);
// points[2].cut(borders[6],pInt);
// this.cut(this.borders[b],pInt);
// this.borders[b].updateMiddle();
//3,6
// borders[3].updateMiddle();
// dsh(borders[0].disFromPoint({x:158,y:122.5}));
// points[5].cut(borders[2],{x: 241.5, y: 269.5});
console.log(points,borders);
/*-------------------------------------END sandBox -------------------*/
for(b in borders){
borders[b].show();
}
}
function getMap(){
var mapSync = [];
for(var i = 0; i<10; i++){
var line = '';
for(var j = 0; j < 10; j++){
var c = Math.round(Math.random() * 0.8);
line += c;
}
dsh(line);
mapSync.push(line);
}
// mapSync = [ //error new about edge
// "0000000000",
// "0000001100",
// "0000010010",
// "0000001100",
// "0000010010",
// "0000001100",
// "0000000000",
// "0000000000",
// "0000000000",
// "0000000000"];
canvasApp(mapSync);
}
/*--------------------------------- cordinate mouse ---------------*/
function writeMessage(canvas, message) {
var context = canvas.getContext('2d');
context.canvas.width = W;
context.canvas.height = H;
context.clearRect(0, 0, canvas.width, canvas.height);
context.font = '14pt Calibri';
context.fillStyle = 'black';
context.fillText(message, W/2, 25);
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
// var canvas = document.getElementById('map');
// var context = canvas.getContext('2d');
</script>
</head>
<body>
<button onclick="getMap()">New Map</button><br><br>
<canvas id="map"></canvas>
<canvas id="cordinate" style="border:0px solid red;"></canvas>
</body>
</html>
function Point(x, y){
this.x = x;
this.y = y;
this.i = null;
this.lines = [];
this.borders = [];
this.dist = [];
}
Point.prototype = {
}
/*---------------------------------------------------------- setDis
* Input: Point, node:Point, dis:number
* Output: -
* Description: add one element to dist[]
--------------------------------------------------------------------*/
Point.prototype.setDis = function(node,dis){
this.dist.push({point:node,dis:dis});
}
/*---------------------------------------------------------- sortDis
* Input: Point
* Output: -
* Description: calculate level of points by distance the this node
--------------------------------------------------------------------*/
Point.prototype.sortDis = function(){
for(i in this.dist){
var max = Infinity;
var node = null;
for(j in this.dist){
if(this.dist[j].level == undefined){
if(this.dist[j].dis < max){
max = this.dist[j].dis;
node = j;
}
}
}
this.dist[node].level = i;
}
}
/*---------------------------------------------------------- sortDis
* Input: Point, level:number
* Output: Point
* Description: return the n's level of neighbor of point
--------------------------------------------------------------------*/
Point.prototype.findNeighbor = function(level){
for(i in this.dist){
if(this.dist[i].level == level)
return this.dist[i].point;
}
}
/*---------------------------------------------------------- findCrossoverBorders
* Input: Point, Point
* Output: Borders[]
* Description: this methos find all crossover borders in the target between points
IMPORTANT: we need to optimize the codes to just find crossover by point's borders
*--------------------------------------------------------------------*/
Point.prototype.findCrossoverBorders = function(point,edge){
var tmpBorder = new Border(this.x,this.y,point.x,point.y);
var arr = [];
for(i in borders){
var p = tmpBorder.findIntersectionBorder(borders[i]);
if(p)
arr.push(borders[i]);
if(edge && tmpBorder.isOnEdge(p))
arr.pop();
}
// tmpBorder.show('black'); //delete
return arr;
}
/*---------------------------------------------------------- isTargetOpen
* Input: Point, Point
* Output: Boolean
* Description: find the wall between two point
*--------------------------------------------------------------------*/
Point.prototype.isTargetOpen = function(point,edge){
var arr = this.findCrossoverBorders(point,edge);
if(arr.length)
return false
return true;
}
/*---------------------------------------------------------- disFromPoint
* Input: Point, Point
* Output: Number
* Description: this are different with same name method in borders. in this part
we calculate the distance between two point by simple formula
*--------------------------------------------------------------------*/
Point.prototype.disFromPoint = function(point){
return Math.sqrt( p2(this.x - point.x) + p2(this.y - point.y) );
}
/*-------------------------------------------------------------- show
* Input: Point, [x]:number, [y]:number, [color]:string, [msg]:string
* Output: DRAW
* Description: to draw a point with a massage, it can use another point if
x and y have value
--------------------------------------------------------------------*/
Point.prototype.show = function(color,x,y,msg){
if(!x || !y){
x = Math.round(this.x);
y = Math.round(this.y);
}
else{
x = Math.round(x);
y = Math.round(y);
}
context.beginPath();
context.arc(x, y, 5, 0, 2 * Math.PI, false);
context.fillStyle = 'yellow';
context.fill();
context.font = '10pt Calibri';
if(!color)
context.fillStyle = 'yellow';
else
context.fillStyle = color;
if(!msg)
msg = '';
context.fillText(''+x+','+y+' '+msg, x,y - 15);
context.fill();
}
/*-------------------------------------------------------------- show
* Input: Point, Border, Point
* Output: -
* Description: trim border acording to the nearest part of border by point
we choose a point outside the border to cut the border acording to the point
and also checking nearest and have open target to the parts of border
--------------------------------------------------------------------*/
Point.prototype.cut = function(border,point){
// var tmpPoint = new Point(point.x,point.y);
// dsh(border.isOnBorder(point));
if(!border.isOnBorder(point))
return false;
if(border.isOnEdge(point))
return false;
var part1 = new Border(border.x0,border.y0,point.x,point.y);
var part2 = new Border(border.x1,border.y1,point.x,point.y);
// var m1 = new Point(part1.xm,part1.ym);
// var m2 = new Point(part2.xm,part2.ym);
var m1 = part1.nearPointToEdge(point);
var m2 = part2.nearPointToEdge(point);
// if(border.i == 54){
// // dsh(this.i,border.i,point.x,point.y,m2 );
// // dsh(this.findCrossoverBorders(m1,true));
// m1.show('brown');
// m2.show();
// // dsh(m1,m2);
// part1.show('black',4);
// part2.show('red',4);
// }
// dsh('m1',this.isTargetOpen(m1,true));
// dsh('m2',this.isTargetOpen(m2,true));
// console.log('cut',this.isTargetOpen(m1,true));
// if both open or both close we choose the nearest part
if((this.isTargetOpen(m1,true) && this.isTargetOpen(m2,true)) || (!this.isTargetOpen(m1,true) && !this.isTargetOpen(m2,true))){
if(part1.disFromPoint(this) < part2.disFromPoint(this)){
border.x0 = part1.x0;
border.y0 = part1.y0;
border.x1 = part1.x1;
border.y1 = part1.y1;
}
else{
border.x0 = part2.x0;
border.y0 = part2.y0;
border.x1 = part2.x1;
border.y1 = part2.y1;
}
return true;
}
if(this.isTargetOpen(m1,true)){
border.x0 = part1.x0;
border.y0 = part1.y0;
border.x1 = part1.x1;
border.y1 = part1.y1;
}
else{
border.x0 = part2.x0;
border.y0 = part2.y0;
border.x1 = part2.x1;
border.y1 = part2.y1;
}
}
Point.prototype.createPerpendicular = function(point){
if(this.isHaveCommonBorder(point))
return false;
var tmpBorder = new Border(this.x,this.y,point.x,point.y);
tmpBorder.returnABC();
perBorder = new Border();
perBorder.A = - tmpBorder.B;
perBorder.B = tmpBorder.A;
var x = (point.x + this.x) / 2;
var y = (point.y + this.y) / 2;
perBorder.C = -(perBorder.A * x + perBorder.B * y);
perBorder.point1 = this;
perBorder.point2 = point;
x1 = 0;
if(perBorder.B != 0){
y1 = (-perBorder.A * x1 - perBorder.C)/perBorder.B;
if(y1 > H){
y1 = H;
x1 = (-perBorder.B * y1 - perBorder.C)/perBorder.A;
}
if(y1 < 0){
y1 = 0;
x1 = (-perBorder.B * y1 - perBorder.C)/perBorder.A;
}
}
else{
y1 = 0;
x1 = - perBorder.C / perBorder.A;
}
x2 = W;
if(perBorder.B != 0){
y2 = (-perBorder.A * x2 - perBorder.C)/perBorder.B;
if(y2 > H){
y2 = H;
x2 = (-perBorder.B * y2 - perBorder.C)/perBorder.A;
}
if(y2 < 0){
y2 = 0;
x2 = (-perBorder.B * y2 - perBorder.C)/perBorder.A;
}
}
else{
y2 = H;
x2 = - perBorder.C / perBorder.A;
}
perBorder.x0 = x1;
perBorder.y0 = y1;
perBorder.x1 = x2;
perBorder.y1 = y2;
//DSH Note : i must optimize this code
for(b in this.borders){
var pInt = this.borders[b].findIntersectionBorder(perBorder);
if(pInt){
this.cut(perBorder,pInt);
this.cut(this.borders[b],pInt);
this.borders[b].updateMiddle();
}
}
for(b in point.borders){
var pInt = point.borders[b].findIntersectionBorder(perBorder);
if(pInt){
point.cut(perBorder,pInt);
point.cut(point.borders[b],pInt);
point.borders[b].updateMiddle();
}
}
for(b in borders){
var pInt = borders[b].findIntersectionBorder(perBorder);
if(pInt){
this.cut(perBorder,pInt);
// this.cut(this.borders[b],pInt);
// this.borders[b].updateMiddle();
}
}
perBorder.updateMiddle();
// if(this.i == 2 && point.i == 3){
// perBorder.show('red');
// n32 = perBorder.returnPointMirror(points[2]);
// this.show('brown',n32.x,n32.y);
// }
// if(this.isTargetOpen(perBorder.returnMiddle(),true)){ //returnMiddle() change to returnPointMirror()
// this.addBorder(perBorder);
// point.addBorder(perBorder);
// borders.push(perBorder);
// }
if(this.isTargetOpen(perBorder.returnPointMirror(this),true)){
this.addBorder(perBorder);
point.addBorder(perBorder);
borders.push(perBorder);
}
return perBorder;
}
Point.prototype.addBorder = function(border){
this.borders.push(border);
}
Point.prototype.isHaveCommonBorder = function(point){
for(i in this.borders){
if((this.borders[i].point1 == this && this.borders[i].point2 == point) || (this.borders[i].point1 == point && this.borders[i].point2 == this))
return true;
}
return false;
}
/*---------------------------------------------------------- pruningExtraBorder
* Input: Point
* Output: true
* Description: delete free borders that outside the shape.
*--------------------------------------------------------------------*/
Point.prototype.pruningExtraBorder = function(){
for(var i=0; i<this.borders.length; i++){
var state = this.isTargetOpen(this.borders[i].returnMiddle(),true);
if(this.i == 3){
dsh(this.i,state,this.borders);
}
if(!state){
deleteBorderByIndex(this.borders[i].i);
this.borders.splice(i,1);
i--;
}
}
return true;
}
/*---------------------------------------------------------- showShape
* Input: Point
* Output: -
* Description: show all borders in point
*--------------------------------------------------------------------*/
Point.prototype.showShape = function(){
for(var i=0; i<this.borders.length; i++){
this.borders[i].show('red');
}
}
/*---------------------------------------------------------- Border
* Input1: x0:number, y0:number, x1:number, y1:number
* Input2: Point,Point
* Description: to create Border object by cordinate or points
--------------------------------------------------------------------*/
function Border(x0,y0,x1,y1){
if(typeof(x0) === 'object' && typeof(y0) === 'object'){
x1 = y0.x;
y1 = y0.y;
y0 = x0.y;
x0 = x0.x;
}
this._construct(x0,y0,x1,y1);
}
Border.counter = 0;
Border.prototype = {
_construct : function(x0,y0,x1,y1){
// strat and end of each border, this variables updatedeach time.
this.x0 = x0;
this.y0 = y0;
this.x1 = x1;
this.y1 = y1;
// Standard formula [Ax + By + C = 0]
this.A = y0 - y1;
this.B = x1 - x0;
this.C = x0 * y1 - x1 * y0;
// we have two Point for each border for recognize them
this.point1 = null;
this.point2 = null;
// medium of border
this.xm = (x0+x1)/2;
this.ym = (y0+y1)/2;
//length of border
this.long = Math.sqrt(p2(x1-x0) + p2(y1-y0));
Border.counter++;
this.i = Border.counter;
},
};
/*-------------------------------------------------------------- show
* Input: Border , [color]:string
* Output: DRAW
* Description: to draw a border
--------------------------------------------------------------------*/
Border.prototype.show = function(color,width){
if(!this.x0 || !this.x1){
x1 = 0;
if(this.B != 0)
y1 = (-this.A * x1 - this.C)/this.B;
else{
y1 = 0;
x1 = - this.C / this.A;
}
x2 = W;
if(this.B != 0)
y2 = (-this.A * x2 - this.C)/this.B;
else{
y2 = H;
x2 = - this.C / this.A;
}
}
x1 = this.x0;
y1 = this.y0;
x2 = this.x1;
y2 = this.y1;
context.beginPath();
context.lineWidth = width?width:2;
if(!color)
context.strokeStyle = '#0000ff';
else
context.strokeStyle = color;
context.moveTo(x1,y1);
context.lineTo(x2,y2);
context.stroke();
context.font = '10pt Calibri';
context.fillStyle = 'orange';
// context.fillText(this.i, this.xm,this.ym);
// context.fill();
}
/*---------------------------------------------------------- returnABC
* Input: Border
* Output: {A,B,C}
* Description: this is not useful after version 3
--------------------------------------------------------------------*/
Border.prototype.returnABC = function(){
if(this.A === null){
this.A = this.y0 - this.y1;
this.B = this.x1 - this.x0;
this.C = this.x0 * this.y1 - this.x1 * this.y0;
}
return {A:this.A,B:this.B,C:this.C}
}
/*---------------------------------------------------------- findIntersectionBorder
* Input: Border, Border
* Output: Boolean | cordinate as {x,y}
* Description: find the point of Intersection between two border
--------------------------------------------------------------------*/
Border.prototype.findIntersectionBorder = function(b){
var l1 = this.returnABC();
var l2 = b.returnABC();
var det = l2.A*l1.B - l1.A*l2.B;
if(det == 0){
return false;//this part need to be tested
}
else{
var x = (l2.B*l1.C - l1.B*l2.C) / det;
var y = (l1.A*l2.C - l2.A*l1.C) / det;
var tmpDot = new Point(x,y);
// tmpDot.show();//delete
if(!this.isOnBorder(tmpDot) || !b.isOnBorder(tmpDot))
return false;
return tmpDot;
}
}
/*---------------------------------------------------------- isOnBorder
* Input: Point, Border
* Output: Boolean
* Description: find the point is on border or not
--------------------------------------------------------------------*/
Border.prototype.isOnBorder = function(point){
var tmpPoint = new Point(point.x,point.y);
if(!snap(this.disFromPoint(tmpPoint)))
return true;
else
return false;
}
/*---------------------------------------------------------- disFromPoint
* Input: Point, Border
* Output: Number
* Description: first check to find the point is in range, be aware this type of
distance is not real distance, for wxample if the point is out of range method
calculate distance from the edge of border
*--------------------------------------------------------------------*/
Border.prototype.disFromPoint = function(point){
var p = new Point(point.x,point.y);
// p.show();
if(this.isInRange(point)){
p = null;
delete p;
return Math.abs(this.A*point.x + this.B*point.y + this.C) / Math.sqrt(p2(this.A) + p2(this.B));
}
else{
var dis1 = p.disFromPoint({x:this.x0,y:this.y0});
var dis2 = p.disFromPoint({x:this.x1,y:this.y1});
p = null;
delete p;
return Math.min(dis1,dis2);
}
}
/*---------------------------------------------------------- isInRange
* Input: Point, Border
* Output: Boolean
* Description: create rectangle by the node of border and check point
to recognize if inside the rectangle or not.
*--------------------------------------------------------------------*/
Border.prototype.isInRange = function(point){
var x = (this.B * (this.B * point.x - this.A * point.y) - this.A * this.C) / (p2(this.A)+p2(this.B));
var y = (this.A * (-this.B * point.x + this.A * point.y) - this.B * this.C) / (p2(this.A)+p2(this.B));
/*------------------------------*/
if(this.B != 0){
var maxX = (this.x0 > this.x1)? this.x0:this.x1;
var minX = (this.x0 < this.x1)? this.x0:this.x1;
}
else{
var minX = 0;
var maxX = W;
}
if(this.A != 0){
var maxY = (this.y0 > this.y1)? this.y0:this.y1;
var minY = (this.y0 < this.y1)? this.y0:this.y1;
}
else{
var minY = 0;
var maxY = H;
}
if(x >= minX && x <= maxX && y >= minY && y <= maxY)
return true;
return false;
}
/*---------------------------------------------------------- returnY
* Input: x:number, Border
* Output: Boolean | number
* Description: use as f(x)
*--------------------------------------------------------------------*/
Border.prototype.returnY = function(x){
if(this.B)
return (-this.A*x -this.C)/this.B
else
return this.ym;
}
/*---------------------------------------------------------- returnX
* Input: y:number, Border
* Output: Boolean | number
* Description: use as f(y)
*--------------------------------------------------------------------*/
Border.prototype.returnX = function(y){
if(this.B)
return (-this.B*y -this.C)/this.A
else
return this.xm;
}
/*---------------------------------------------------------- isOnEdge
* Input: Border, Point
* Output: Boolean
* Description: check the point is one of the edge of border, IMPORTANT:
snap must be active in this method
*--------------------------------------------------------------------*/
Border.prototype.isOnEdge = function(point){
var x0 = floor(this.x0);
var y0 = floor(this.y0);
var x1 = floor(this.x1);
var y1 = floor(this.y1);
var x = floor(point.x);
var y = floor(point.y);
if((x0 == x && y0 == y) || (x1 == x && y1 == y))
return true;
// if( (!snap(this.x0 - point.x) && !snap(this.y0 - point.y)) || (!snap(this.x1 - point.x) && !snap(this.y1 - point.y)) )
// return true;
return false
}
/*---------------------------------------------------------- updateMiddle
* Input: Border
* Output: {x,y}
* Description: calculate xm and ym again after cut
*--------------------------------------------------------------------*/
Border.prototype.updateMiddle = function(){
this.xm = (this.x0+this.x1)/2;
this.ym = (this.y0+this.y1)/2;
}
/*---------------------------------------------------------- returnMiddle
* Input: Border
* Output: {x,y}
* Description: cordination middle of the border
*--------------------------------------------------------------------*/
Border.prototype.returnMiddle = function(){
return ({x:this.xm,y:this.ym});
}
/*---------------------------------------------------------- calculateAngle
* Input: Border
* Output: number
* Description: calculate angle of border in radian
*--------------------------------------------------------------------*/
Border.prototype.calculateAngle = function(){
return Math.atan2(Math.abs(this.y0 - this.y1),Math.abs(this.x0 - this.x1) );
}
/*---------------------------------------------------------- returnType
* Input: Border
* Output: string
* Description: find the type of border, weh have {up(/), down(\),
vertical(-), horizontal(|)}
*--------------------------------------------------------------------*/
Border.prototype.returnType = function(){
var tmp = (-this.A)/this.B;
if(tmp == Infinity || tmp == -Infinity)
return 'vertical';
else if(tmp == 0)
return 'horizontal';
else if(tmp < 0)
return 'up';
else if(tmp > 0)
return 'down';
else
return 'error';
}
/*---------------------------------------------------------- nearPointToEdge
* Input: Border,Point
* Output: Point
* Description: find the near point to edge by SNAP
*--------------------------------------------------------------------*/
Border.prototype.nearPointToEdge = function(point){
var d = SNAP * 100000;
// var d = 20;
var k = this.long / d;
var x0,y0,x1,y1;
if(point.x == this.x0 && point.y == this.y0){
x0 = this.x0;
y0 = this.y0;
x1 = this.x1;
y1 = this.y1;
}
else if(point.x == this.x1 && point.y == this.y1){
x0 = this.x1;
y0 = this.y1;
x1 = this.x0;
y1 = this.y0;
}
else{
console.error('ERROR >> nearPointToEdge');
return false;
}
var x = ((k-1) * x0 + x1) / k;
var y = ((k-1) * y0 + y1) / k;
var tmpPoint = new Point(x,y);
// tmpPoint.show('yellow');
return tmpPoint;
}
/*---------------------------------------------------------- returnPointMirror
* Input: Border, Point
* Output: Point | {x,y}
* Description: find the mirror on the border.
*--------------------------------------------------------------------*/
Border.prototype.returnPointMirror = function(point){
var x = (this.B * (this.B * point.x - this.A * point.y) - this.A * this.C) / (p2(this.A) + p2(this.B));
var y = (this.A * (-this.B * point.x + this.A * point.y) - this.B * this.C) / (p2(this.A) + p2(this.B));
var tmpPoint = new Point(x,y);
if(this.isOnBorder(tmpPoint))
return tmpPoint;
else{
this.updateMiddle();
return this.returnMiddle();
}
// tmpPoint.show('brown');
// return tmpPoint;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment