Algorithm for searching a grid radially from a point - javascript

I have an object that sits at point 0,0. This object cannot share space with any other object of its type that may appear on top of it, next to it, above it, etc.. There may be more than a few of these objects present overlapping each other and i have no knowledge of where the other ones are placed until i try the collision detection method.
My thinking is that i'll use a collision detection along side a grid search. Along the lines of the photo below.
The object will first try its default best case location. If that doesn't work then it tries to the left, left-above, left-below, etc, until it has searched all the #1 positions. Then it moves onto the #2 positions and so on until it finds a place to drop the element where it won't be overlapping another.
this is the code i'm playing around with right now but it is choosing some very, very random locations for things. I'm pretty sure it isn't following the algorithm i described above.
for (let i = 0; i < 5 && this._hasCollisions(this._tagWrapper); i++) {
/**
* This algorithm explores positions inside nested boxes.
* The move algorithm behaves the following way. It goes,
* down, up, left, down, up, right * 2, repeat.
*
* For example this is how it works given the height of 5 and a width of 7
* numbers are expressed in the offset generated
* 1: 5,0 4: 5,-7 7: 5,7 10: 10,-14
* 2: -5,0 5: -5,-7 8: -5,7 11: -10,-14
* 3: 0,-7 6: 0,7 9: 0,-14
*/
// Calculate which box the collision detector is working in
// This happens every 9 iterations
let multiplier = (i / 9) + 1;
/**
* Get the x offset
*/
if (i % 3 === 0) {
// Clear the height offset on multiples of 3
xOffset = 0;
} else {
// Set the height to the multiplier
xOffset = this._tagWrapper.offsetWidth * multiplier;
}
if (i % 3 === 2) {
// Get the sequence 2, 5, 8, 11, 14, etc..
xOffset *= -1;
}
/**
* Get the y offset
*/
if (i > 2) {
// Set the width to a multiple of the multiplier and assign the existing negativeness
yOffset = this._tagWrapper.offsetHeight * multiplier * (yOffset > 0 ? 1 : -1);
}
if (i % 3 === 0) {
// Flip the sign every 3 numbers
yOffset *= -1;
}
console.log('iteration', i);
this._tagWrapper.style.top = (basePosition.y + yOffset) + 'px';
this._tagWrapper.style.left = (basePosition.x + xOffset) + 'px';
}
What is the best way to go about performing this search? I already hav

Something like this work? (most of the code is just for the visualization)
// just draw a table to visualize
var SIZE = 15;
for (var i = 0; i < SIZE; i++) {
$("#a").append("<tr>");
for (var j = 0; j < SIZE; j++) {
$("#a > tr").last().append("<td>.</td>");
}
}
// where to start searching from
var startX = 8;
var startY = 8;
function loop() {
// tell the world which grid we are on
$("#a > tr:nth-child(" + y + ") > td:nth-child(" + x + ")").css("backgroundColor", "red");
// check if done here!!! - x and y are our positions in the grid
// also do bounds checking here
if (isX) {
x = x + xDirection;
i--;
if (!i) {
// switch dimension
isX = !isX;
i = moveFor;
// switch direction
xDirection *= -1;
}
} else {
y = y + yDirection;
i--;
if (!i) {
// switch dimension
isX = !isX;
// increase the width / height we are spanning
moveFor += 1;
i = moveFor;
// switch direction
yDirection *= -1;
}
}
// jsut so that we have a nice animation
if (x > 0 && y > 0 && x <= SIZE && y <= SIZE) {
setTimeout(loop, 10)
}
}
var x = startX;
var y = startY;
var moveFor = 1;
// our step (down) counter
var i = moveFor;
var xDirection = -1;
var yDirection = -1;
// are we moving along x or y
var isX = true;
loop();
body {
font-family: monospace;
}
td {
height: 20px;
width: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody id="a"></tbody>
</table>

I would suggest using distance solution
point1 has x1 and y1
point2 has x2 and y2
var d = Math.sqrt( (x2-=x1)*x2 + (y2-=y1)*y2 );
link here: Get distance between two points in canvas

Here is an implementation of scanning points in a ring around a center point. You define the center point and the distance you want to sample and it returns the list of points in clock-wise order. It is in Python not JavaScript but it is simple enough that you can translate if needed.

Related

Getting X and Y coordinates from tile ID

I'm stumped on what is probably some pretty simple math. I need to get the X and Y coordinates from each tiles referenced ID. The grid below shows the order the ids are generated in. Each tile has a width and height of 32. Number ones x & y would be equal to (0,0). This is for a game I'm starting to make with canvas using a tileset.
1|2|3
4|5|6
7|8|9
So far for X, I've come up with...
(n % 3) * 32 - 32 // 3 is the width of the source image divded by 32
And for Y...
(n / 3) * 32
This is obviously wrong, but It's the closest I've come, and I don't think I'm too far off from the actual formula.
Here is my actual code so far:
function startGame() {
const canvas = document.getElementById("rpg");
const ctx = canvas.getContext("2d");
const tileSet = new Image();
tileSet.src = "dungeon_tiles.png";
let map = {
cols: 10,
rows: 10,
tsize: 32,
getTileX: function(counter, tiles) {
return ((tiles[counter] - 1) % 64) * 32;
},
getTileY: function(counter, tiles) {
return ((tiles[counter] - 1) / 64) * 32;
}
};
let counter = 0;
tileSet.onload = function() {
for (let c = 0; c < map.cols; c++) {
for (let r = 0; r < map.rows; r++) {
let x = map.getTileX(counter, mapObj.layers[0].data); // mapObj.layers[0].data is the array of values
let y = map.getTileY(counter, mapObj.layers[0].data);
counter += 1;
ctx.drawImage(
tileSet, // image
x, // source x
y, // source y
map.tsize, // source width
map.tsize, // source height
r * map.tsize, // target x
c * map.tsize, // target y
map.tsize, // target width
map.tsize // target height
);
}
}
};
}
If 1 is (0,0) and each tile is 32*32, then finding your horizontal position is a simple 32*(t-1) where t is your tile number. t-1 because your tiles start from 1 instead of 0. Now, you have 3 tiles per row so you want to reset every 3, so the final formula for your x is 32*((t-1)%3).
For the vertical position it's almost the same, but you want to increase your position by 32 only once every 3 tiles, so this is your y: 32*floor((t-1)/3).
floor((t-1)/3) is simply integer division since the numbers are always positive.
If I understand this correctly, you want to get the 1|2|3 values based on x, y correct? You can do something like this:
((y * total # of rows) + x) + 1
This would convert the 2D x, y index to a single index which is, as you stated, 1|2|3. This formula is based on your example where count starts at 1 and not 0. If you want to convert it to 0 base, just remove the + 1.
If you have the width and height, or probably location of input/character, you can have a GetX(int posX) and GetY(int posY) to get the x and y based on the position. Once you have converted the position to x, y values, use the formula above.
int GetX(int posX)
{
return (posX / 32);
}
int GetY(int posY)
{
return (posY / 32);
}
int GetIndex(int posX, int posY)
{
return ((GetY(posY) / totalRows) + GetX(posX)) + 1;
}

p5.js object collision and objects entangling

I wrote some code in p5.js to see if i can properly make a collision detection system but when i put more than 2 squares in, squares seem to bump each other inside of other squares. I'd like to know if there's anyway to stop this plus, if you have any good pointers on how to do tidy/shorten my code id like to hear them.
My code:
var r; //later defined as an array for the squares
var num; //number of squares
function setup(){
r = [];
num = 10;
createCanvas(windowWidth,windowHeight- 4);
for(var i = 0;i < num; i++){
r[i] = new Box(random(width-40),random(height-40),40,40);
}
}
function draw(){
background(40);
for(var i = 0;i < num; i++) {
r[i].show();
for(var j = 0;j<num; j++){
//this is the if statement evaluating if the left and right of the square is touching each other. i is one square and j is the other. you see in each if statement i have the acceleration being added, this is because if it wasn't then they would be true if the squares were touching each other on any side
if(r[i].right+r[i].xa >= r[j].left && r[i].bottom >= r[j].top && r[i].top <= r[j].bottom && r[i].left + r[i].xa <= r[j].right){
r[i].xa *= -1;
r[j].xa *= -1;
}
//this is also just as confusing just read through it carefully
if(r[i].bottom + r[i].ya >= r[j].top && r[i].right >=r[j].left && r[i].left <= r[j].right && r[i].top + r[i].ya <= r[j].bottom){
r[i].ya *= -1;
r[j].ya *= -1;
}
}
}
}
function Box(x, y, wid, hei){
this.x = x;//input for square shape
this.y = y;//ditto
this.width = wid;//ditto
this.height= hei;//ditto
this.xa = random(2,5);//xa is the x acceleration
this.ya = random(2,5);//ya is the y acceleration
this.left;
this.right;
this.top;
this.bottom;
this.show = function(){
this.left = this.x; //i define left,right,top,bottom in show function so they get updated
this.right = this.x +this.width;
this.top = this.y;
this.bottom = this.y +this.height;
push();
fill(255);
noStroke();
rect(this.x,this.y,this.width,this.height);
pop();//push pop just in case i want to change square colors individually in the future
this.x += this.xa;//adding acceleration to the squares
this.y += this.ya;//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if(this.x > width-this.width||this.x <0){//bouncing off the right and left wall
this.xa *= -1;
if(this.x > width/2){// making sure if the square spawns or glitches on the other side of the wall it doesn't get stuck, this checks which side the square is on when it touches the wall then moves it directly on the wall
this.x = width-this.width;
}else{
this.x = 0;
}
}
if(this.y > height-this.height||this.y <0){// same as above but for the y axis
this.ya *= -1;
if(this.y > height/2){
this.y = height-this.height;
}else{
this.y = 0;
}
}
}
}
function windowResized(){
createCanvas(windowWidth,windowHeight- 4);//window resizing adjustment
}
you can view it using this.
just copy and paste.
The solution to the unsolvable
Sorry no such thing
Collision solutions are not easy when you have many moving objects in the scene.
Your immediate problem
Your problem if mainly because you are making an assumption on the box's direction of travel when they collide. You multiply the direction by -1 to reverse direction.
All good for 2 objects, but add a 3rd and you will end up with the 3 coming together. Each in turn you change the direction, box1 hits box2 both move away from each other, then in the same frame box1 hits box3 and now box1 and box3 are moving apart.Your speeds are constant so after a three way collision there will always be 2 boxes traveling in the same direction but overlapping.
The overlapping boxes on the next frame detect the overlap and both reverse direction, as they are already traveling in the same direction the direction switch does not help them move apart.
A step forward
Well a step apart, The following modification to the code just ensures that when possible a collision results in the box move away from each other.
function draw() {
background(40);
for (var i = 0; i < num; i++) {
const bx1 = r[i];
r[i].show();
for (var j = 0; j < num; j++) {
if (j !== i) {
// t for top, b for bottom, r for right and l for left. 1 for first box 2 for second
// bx for box
const bx2 = r[j];
const t1 = bx1.top + bx1.ya;
const b1 = bx1.bottom + bx1.ya;
const l1 = bx1.left + bx1.xa;
const r1 = bx1.right + bx1.xa;
const t2 = bx2.top + bx2.ya;
const b2 = bx2.bottom + bx2.ya;
const l2 = bx2.left + bx2.xa;
const r2 = bx2.right + bx2.xa;
// the or's mean that the condition will complete at the first passed clause
// If not (not over lapping) AKA is overlapping
if (!(t1 > b2 || b1 < t2 || l1 > r2 || r1 < l2)) {
if (r1 >= l2) {
bx1.xa = -Math.abs(bx1.xa);
bx2.xa = Math.abs(bx2.xa);
}
if (l1 <= r2) {
bx1.xa = Math.abs(bx1.xa);
bx2.xa = -Math.abs(bx2.xa);
}
if (b1 >= t2) {
bx1.ya = -Math.abs(bx1.ya);
bx2.ya = Math.abs(bx2.ya);
}
if (t1 <= b2) {
bx1.ya = Math.abs(bx1.ya);
bx2.ya = -Math.abs(bx2.ya);
}
}
}
}
}
}
But that only moves the problem away from overlapping, now there are many collision that are wrong as there is no test to determine the point of collision
In the above code you are trying to solve from an unsolvable position. Boxes in real life never overlap. Boxes in real life will slow down and speed up. perfectly flat sides will never collide with more than on side at a time.
To do this you will need to use integration. Its not that hard and is just a process of dividing time into smaller steps. Collide, move, check for overlap, move apart then back to collide.
Verlet integration
Also verlet integration will make it easier. Rather than store a boxes speed as a vector you store the current position and the previous position.
box.x = 10;
box.y = 10;
box.ox = 8; // the boxes old position
box.oy = 8;
You move a box as follows
sx = box.x - box.ox;
sy = box.y - box.oy;
box.ox = box.x;
box.oy = box.y;
box.x += sx; // the boxes old position
box.y += sy;
When you hit something you need to change the old position so as to give the next iteration the correct direction
if(box.y > ground){
box.y = ground - (box.y - ground); // move away from ground same dist as moved into ground
box.oy = box.y -sy;
}
Do them all in groups.
Move all at once, then test for collision at once. Dont move and test one at a time.
Verlet integration is much more forgiving as it lets speed of movement absorb some of the error. Rather than be all in position as the standard vector method does.

Can I get help on a Rectilinear Polygon Hull Algorithm (in javascript if possible)

Edited title and here to reflect my question better.
My first description didn't get answers of the kind I was looking for and I didn't know there was a fancy name for this kind of shape I'm trying to make.
I studied Graham Scan algorithms but they don't completely cover the answer I'm looking for either, as they tend to "cut corners" if the shape becomes strange say.
Based on some articles I found, I'd started writing my own algorithm and it works a lot of the cases to be sure but I keep coming into problems I cant seem to completely stamp out, I believe the problem might be where I'm trying to calculate each of the corners.
This is the logic of my algorithm -
1st = Find the corners, top-left, top-right, bottom-right, bottom-left
2nd = Enter a while loop, travelling towards a target, starting from top-left travelling to top-right then to bottom right to bottom left and back to top left.
3rd = in each iteration of this while loop, we find the neighbours of each tile if they exist in this list, and choose the next tile to travel to, based on which comes first in an order decided by priority.
Priority explained, if the priority is to get to the top right corner, we take our time by first trying to travel to the left, then up, right and down but ONLY if a tile in this direction exists and ONLY if this tile isn't the previous tile we were standing at.
After we arrive at the top right corner, we shift the priority list making the first priority become the last. So
priority = [left, up, right, down]
becomes
priority = [up, right, down, left]
In the majority of cases my code IS performing as expected, like the logic seems sound, but there are a few anomaly moments where it doesn't seem to pick the right tile based on the priority I'm giving it and instead it wanders about the whole array. If anyone can help me where I'm making a mistake I'd appreciate this.
Heres my current algorithm code >
draw_hull = function() {
var list = [],
coordinates = [],
original_list = this.territory,
_x = 0, // coords are in arrays, [x,y] style.
_y = 1; // this is just for readers readability
// make list to be looped through, for each tile I deliberately added 4,
//it'll look more readable in the final product.
for (var i = 0; i < original_list.length; i++) {
list.push( [ (original_list[i][_x] * 32) + 8, (original_list[i][_y] * 32) + 8 ] );
list.push( [ (original_list[i][_x] * 32) + 24, (original_list[i][_y] * 32) + 8 ] );
list.push( [ (original_list[i][_x] * 32) + 24, (original_list[i][_y] * 32) + 24 ] );
list.push( [ (original_list[i][_x] * 32) + 8, (original_list[i][_y] * 32) + 24 ] );
}
// find corners
var topleft = 0, topright = 0, bottomright = 0, bottomleft = 0, hull = [];
for (var i = 0; i < list.length; i++) {
var x = list[i][_x];
var y = list[i][1];
if (x <= list[topleft][_x] && y <= list[topleft][_y]) topleft = i;
if (x >= list[topright][_x] && y <= list[topright][_y]) topright = i;
if (x >= list[bottomright][_x] && y >= list[bottomright][_y]) bottomright = i;
if (x <= list[bottomleft][_x] && y >= list[bottomleft][_y]) bottomleft = i;
}
// start drawing paths from one corner to the next, repeating until a full loop has been made
var priorities = ["l","u","r","d"], // travel the outline in this order, left up right down
current = topleft, // current tile
last = topleft; // last tile
target = [topright,bottomright,bottomleft,topleft],
target_iterator = 0, // target iterator so we know which corner we're striving towards
xx = 0, // an iterator to make sure this loop doesnt go on forever
done = false;
while(!done) {
// add the current tile to our hull list.
hull.push(current);
var next = {},
cx = list[current][_x],
cy = list[current][_y];
for (var i = 0; i < list.length; i++) {
var x = list[i][_x], y = list[i][_y];
if (x === cx && y === cy -16) { next.up = i; continue; }
if (x === cx && y === cy +16) { next.down = i; continue; }
if (x === cx -16 && y === cy) { next.left = i; continue; }
if (x === cx +16 && y === cy) { next.right = i; continue; }
}
var i = 0, check = priorities;
for (var i = 0; i < priorities.length; i++) {
var check = priorities[i];
// skip this if next check doesnt exist, or is the tile we just came from
if (next[check] == null || next[check] == undefined|| next[check] === last) continue;
var visited = false;
for (var j = 1; j < hull.length; j++) {
if (hull[j] === next[check]) {
visited = true;
continue;
}
}
if (visited) {
continue;
}
break;
}
last = current;
current = next[check];
xcoords = list[current][_x];
ycoords = list[current][_y];
coordinates.push([xcoords,ycoords]);
if (current === target[target_iterator]) {
priorities.push(priorities.shift());
target_iterator++;
if (target_iterator === 4) break;
}
xx++;
if (xx > 50) {break; debugger;}
}
if (xx < 50) this.hull = coordinates;
}
You should use moveTo() and lineTo() with a stroke(). Further documentation is available at MDN.
A simple drawing function could look like this: (or check Fiddle)
function drawShape(coords) {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.beginPath();
for(var i = 0; i < coords.length; i++) {
if(i === 0) {
ctx.moveTo(coords[i].x, coords[i].y);
} else {
ctx.lineTo(coords[i].x, coords[i].y);
}
}
ctx.closePath();
ctx.stroke();
}
You can easily stroke an "unlimited" amount of corners, or vertices of a shape using moveTo() and lineTo(). Below is an example of how you could draw a triangle, but you could easily extend it by adding more path methods.
var ctx = canvas.getContext('2d');
// Filled triangle
ctx.beginPath();
ctx.moveTo(25,25); //moves 'pen' to coords
ctx.lineTo(105,25); //draws line from prior coords to new specified coords.
ctx.lineTo(25,105);
ctx.fill(); //fills in shape
// Stroked triangle
ctx.beginPath();
ctx.moveTo(125,125);
ctx.lineTo(125,45);
ctx.lineTo(45,125);
ctx.closePath();
ctx.stroke(); //strokes along path (i.e shape outline)
<canvas id="canvas" width="200" height="200"></canvas>
This code can be found at https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes along with detailed advice on how to draw more complex shapes.
Ok, further studies, I found a name for the type of shape I'm trying to draw.
Its called an Rectilinear polygon.
Wikipedia's article
Stack Overflow already has an answer for this, was just hard to find.

Paper.js: fastest way to draw many iterated shapes over loop

jsfiddle here: http://jsfiddle.net/yw0w18m3/2/
I'm using paper.js to make a background image that looks somthing like this:
Basically, I'm creating a couple thousand triangles over a loop and rotating them on every other iteration.
function Tri(x, y, rotate) {
var tri = new Path([
new Point((x - 42), (y - 48)),
new Point((x - 42), y),
new Point(x, (y - 24)),
new Point((x - 42), (y - 48))
]);
tri.fillColor = {
hue: Math.random() * 360,
saturation: 0,
brightness: ( (( Math.random() ) * .95) + .3 )
};
if(rotate) { tri.rotate(180); }
}
for (var i = 0; i < 2000; i++) {
rotate = false;
if( i % 2 ) {
rotate = true;
}
new Tri(x, y, rotate);
x = x + 42;
if( x > (winWidth + 42) ) {
x = 0 ;
y = y + 24;
}
}
There seems to be a brief 1-2 second pause/freeze though while the shapes are being drawn. Is there a more efficient way to draw all the shapes first (or push to an array) then add that to the canvas all at once?
I based my code off of the example here: http://paperjs.org/examples/candy-crash/ (click "source" in the upper right corner).
Any help is much appreciated.
Thanks!
I would end up creating two triangles, one rotated, so they don't have to be built from new points each time. Then choose the correct triangle based on the rotation variable and clone it, as opposed to create points and a triangle from scratch each time. Finally, just change the position of the cloned triangle.
Last, I would correct the maxTri so it doesn't do more than it needs to. The paren should follow the 48, not the 24. You're doing an order of magnitude more triangles than needed.
Here's a link to the sketch.paperjs.org solution I created based on your code. I find sketch easier to use than jsfiddle for paper examples.
proto1 = new Path([
new Point(0, -24),
new Point(0, 24),
new Point(42, 0)
]);
proto1.closed = true;
proto2 = proto1.clone();
proto2.rotate(180);
function putTriangle(pos, rotate) {
var tri = (rotate ? proto2 : proto1).clone();
tri.position = pos;
tri.position = tri.position.subtract([21, 0])
tri.fillColor = {
hue: Math.random() * 360,
saturation: 0,
brightness: Math.random() * 0.5 + 0.5
}
}
var tris = [],
x = 42,
y = 24,
rotate,
winWidth = paper.view.size.width,
winHeight = paper.view.size.height,
rows = (winHeight + 48) / 24,
cols = (winWidth + 42) / 42,
numTri = rows * cols,
numTriOrig = (winWidth + 42) / 42 * (winHeight + 48 / 24);
//console.log(numTri, numTriOrig);
x = 0;
y = 0;
for (var row = 0; row < rows; row++) {
rowrotate = row % 2;
for (var col = 0; col <= cols; col++) {
rotate = rowrotate ^ col % 2;
putTriangle([x,y], rotate);
x += 42;
}
x = 0;
y = y + 24;
}
Two thoughts:
I see you use rotate to transform you triangles into place. This is an expensive operation. You could replace the rotate with a less geometric & more arithmetic calculation of the triangles orientation.
Also, I see is that the fill color is being changed with each triangle and state changes (like fill) are modestly expensive. You could group all the similarly colored triangles and draw them in a single batch.

How to move a marker on a straight line between two coordinates in Mapbox.js

Below is some code I found for moving a marker but I want to move a marker on straight path between two coordinates can any one help these are the coordinates
[90.40237426757811,23.75015391301012],[88.34930419921875,22.573438264572406]
I need the coordinates between these two points for a line. The code is:
var marker = L.marker([0, 0], {
icon: L.mapbox.marker.icon({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-77, 37.9]
},
properties: { }
})
});
var t = 0;
window.setInterval(function() {
// making a lissajous curve here just for fun. this isn't necessary
// Reassign the features
marker.setLatLng(L.latLng(
Math.cos(t * 0.5) * 50,
Math.sin(t) * 50));
t += 0.1;
}, 50);
marker.addTo(map);
How accurate do you need the lines to be? Try something like this to begin with:
var start = {lat:90.40237426757811, lng:23.75015391301012}
var end = {lat:88.34930419921875, lng:22.573438264572406}
var n = 100; // the number of coordinates you want
coordinates = []
for(var i = n - 1; i > 0; i--){
coordinates.push( {lat: start.lat*i/n + end.lat*(n-i)/n,
lng: start.lng*i/n + end.lng*(n-i)/n});
}
This isn't accurate because the world isn't flat and over long distances it will begin to look wrong.
The full maths of plotting straight lines on projected globes is more difficult but there's a great explanation here:
http://www.movable-type.co.uk/scripts/latlong.html
Not far down the page there's a formula to calculate the midpoint of two given points.
Use that formula, then use the midpoint you've found with each end point to find two more points then use those points and so on until you have enough for a smooth line.
This might help. It draws a line between two points on a 2d plane.
fromXy and toXy are arrays containing the coordinates.
pref.canvas.size is and array containing the width and height of the canvas.
pref.color is the color of the pixel you want to print.
setPx() sets a pixel given x and y coordinates and color.
function line(toXy,fromXy) {
var y;
var m = (toXy[1] - fromXy[1]) / (fromXy[0] - toXy[0]);
var b = (m * toXy[0]) + toXy[1];
if (Math.abs(fromXy[0] - toXy[0]) >= Math.abs(fromXy[1] - toXy[1])) {
if (fromXy[0] < toXy[0]) {
for (var x = fromXy[0]; x <= toXy[0]; x++) {
y = m * x - b;
setPx(x,Math.abs(Math.round(y)),pref.color,);
}
} else {
for (var x = fromXy[0]; x >= toXy[0]; x--) {
y = m * x - b;
setPx(x,Math.abs(Math.round(y)),pref.color)
}
}
} else {
if (fromXy[1] <= toXy[1]) {
for (y = fromXy[1]; y <= toXy[1]; y++) {
x = (y / -(m)) + Math.abs(b / -(m));
if (x.toString() == 'Infinity' || x.toString() == 'NaN') {
x = fromXy[0];
}
if (x > pref.canvas.size[0] - 1) {
continue;
}
setPx(Math.abs(Math.round(x)),y,pref.color);
}
} else {
for (y = fromXy[1]; y >= toXy[1]; y--) {
x = (y / -(m)) + Math.abs(b / -(m));
if (x.toString() == 'Infinity' || x.toString() == 'NaN') {
x = fromXy[0];
}
if (x > pref.canvas.size[0] - 1) {
continue;
}
setPx(Math.abs(Math.round(x)),y,pref.color);
}
}
}
}
The code basically builds a linear equation out of the two coordinates then graphs that linear equation.
You should be able to edit the code so that it fits your needs pretty easily.
Thank you all for your useful answers :)
I used the below code for my use case, its not fully correct and with lot of hard-coding too but it worked fr me
here is the link of mock-up app which i developed using this
http://nandinibhotika.com/compass/discover.htm
here is the project description http://nandinibhotika.com/portfolio/compass-exploring-stories/
var geojson = {
type: 'LineString',
coordinates: []
},
start = [90.4010009765625, 23.74763991365265];
geojson.coordinates.push(start.slice());
momentum = [.025, .01429];
for (var i = 0; i < 557; i++) {
if (start[0] > 88.36878921508789 && start[1] > 22.571377617836507) {
start[0] -= momentum[0];
start[1] -= momentum[1];
} else {
momentum = [.00899, .0231];
start[0] += momentum[0];
start[1] -= momentum[1];
}
geojson.coordinates.push(start.slice());
}

Categories

Resources