Calculate distance to move a box to remove intersection - javascript

I have two boxes that are overlapping and I want to figure out how to move one to remove the intersection.
I defined a vector from the center of one box to the other and move one box along that line, but that may be further than it needs to move, or may not be far enough. So I think what I need to do is figure out which corner of the stationary box lines closest to the line between the centers and then figure out how far along that line (or possibly projecting beyond that line) that corner would be. Then I can multiple my vector by that amount, but I'm having trouble wrapping my head around it.
Here's what I have at the moment, I'm adding items with an x,y,width and height property to a list and as I add each item, I'm checking for intersections with items already in the list. If an intersection is found, I try to move the new item and then try again:
function BoxList() {
var self = this;
var boxes = [];
self.add = function(item, iteration) {
// check intersections with existing boxes
iteration = iteration || 0;
if (iteration < 5) {
for (var i=0; i < boxes.length; i++) {
if (doesIntersect(getBounds(item),getBounds(boxes[i]))) {
item.elem.addClass("overlapped");
// Find vector from mid point of one box to the other
var centerA = { x: item.x + item.width / 2, y: item.y + item.height / 2 };
var centerB = { x: boxes[i].x + boxes[i].width / 2, y: boxes[i].y + boxes[i].height / 2 };
var line = { x1 : centerA.x, y1 : centerA.y, x2 : centerB.x, y2 : centerB.y };
var vector = { x : line.x1 - line.x2, y: line.y1 - line.y2 };
item.x = item.x + vector.x;
item.y = item.y + vector.y;
item.elem.offset({ left: item.x , top: item.y }); // TODO: calculate size of move needed
return self.add(item, iteration + 1);
}
}
}
boxes.push(item);
}
function getBounds(item) {
return { x1: item.x, x2: item.x + item.width, y1: item.y, y2: item.y + item.height };
}
function doesIntersect(a,b) {
return a.x1 < b.x2 && a.x2 > b.x1 && a.y1 < b.y2 && a.y2 > b.y1;
}
}
Here's a simple fiddle
Click move to attempt to arrange the two boxes, note that the overlapping box is moved twice and gets moved further than it really needs to.
Any thoughts? Suggestions on better ways to approach this also greatly appreciated.

As I read it now you calculate the centers of both boxes and use those two points to make the vector that pushes one of the boxes. That's the wrong vector. If you place the boxes right on top of each other that vector will be (0,0). If the boxes only just clip each other the vector will be at it's highest possible value.
You can see this in action with the ghosts. First it gets pushed only a little bit, then it gets pushed a lot.
Instead the vector you need should be based on the size of the overlap. If the overlap is 20px by 30px your vector is (+20,+30)
var vector = {
x: Math.min(box1.x + box2.width, box2.x + box2.width) - Math.max(box1.x, box2.x),
y: Math.min(box1.y + box2.height, box2.y + box2.height) - Math.max(box1.y, box2.y)
}
vector.x is the top-right of the bounding box minus the bottom-left of the bounding box. Idem for vector.y.
This moves the box by exactly the right amount: http://jsfiddle.net/x8MT3/2/
I added a 3rd box pair that needs 2 iterations, probably the top box should move the other way. The vector as I've set it up is always (+,+), you can do your center point calculation to determine which sign each direction should have.

Related

Smooth jagged pixels

I've created a pinch filter/effect on canvas using the following algorithm:
// iterate pixels
for (var i = 0; i < originalPixels.data.length; i+= 4) {
// calculate a pixel's position, distance, and angle
var pixel = new Pixel(affectedPixels, i, origin);
// check if the pixel is in the effect area
if (pixel.dist < effectRadius) {
// initial method (flawed)
// iterate original pixels and calculate the new position of the current pixel in the affected pixels
if (method.value == "org2aff") {
var targetDist = ( pixel.dist - (1 - pixel.dist / effectRadius) * (effectStrength * effectRadius) ).clamp(0, effectRadius);
var targetPos = calcPos(origin, pixel.angle, targetDist);
setPixel(affectedPixels, targetPos.x, targetPos.y, getPixel(originalPixels, pixel.pos.x, pixel.pos.y));
} else {
// alternative method (better)
// iterate affected pixels and calculate the original position of the current pixel in the original pixels
var originalDist = (pixel.dist + (effectStrength * effectRadius)) / (1 + effectStrength);
var originalPos = calcPos(origin, pixel.angle, originalDist);
setPixel(affectedPixels, pixel.pos.x, pixel.pos.y, getPixel(originalPixels, originalPos.x, originalPos.y));
}
} else {
// copy unaffected pixels from original to new image
setPixel(affectedPixels, pixel.pos.x, pixel.pos.y, getPixel(originalPixels, pixel.pos.x, pixel.pos.y));
}
}
I've struggled a lot to get it to this point and I'm quite happy with the result. Nevertheless, I have a small problem; jagged pixels. Compare the JS pinch with Gimp's:
I don't know what I'm missing. Do I need to apply another filter after the actual filter? Or is my algorithm wrong altogether?
I can't add the full code here (as a SO snippet) because it contains 4 base64 images/textures (65k chars in total). Instead, here's a JSFiddle.
One way to clean up the result is supersampling. Here's a simple example: https://jsfiddle.net/Lawmo4q8/
Basically, instead of calculating a single value for a single pixel, you take multiple value samples within/around the pixel...
let color =
calcColor(x - 0.25, y - 0.25) + calcColor(x + 0.25, y - 0.25) +
calcColor(x - 0.25, y + 0.25) + calcColor(x + 0.25, y + 0.25);
...and merge the results in some way.
color /= 4;

JavaScript object positioning collision logic

#Pointy:
As I said below, the size variable adjusts the size by a percentage. So this number could have, for example, a value of 1, or 1.5, or 2, etc. The default circle diameter is 100 pixels, and the actual diameter of the circle displayed is size*100. When checking for collision I use size*120 because I want to leave some extra room.
To my understanding, the CSS left and top properties positions the object in terms of its left and top bounds, respectively. Thus if I want to check collision on the right side of the object, I'd have to take the left boundary and add the diameter of the circle (which is given by size*100). When checking the collision on the left side, I take the left bound and subtract size*(1.2-1)*100, because I do not need to account for the diameter of the circle as I am starting from the left bound. The same thing applies to the y-axis.
I hope this was understandable, thanks for helping me out.
Original Post:
I have two circles on my screen, a pink one and a purple one. The positions of these circles (x,y) are randomly determined. Initially, only the purple circle is on the page. One second later, the pink circle will appear. I want to check if these two circles will overlap, and if so, reposition the pink circle.
My code:
if(document.getElementById("purple").style.left+(size*120) > x
&& document.getElementById("purple").style.left-(size*20) < x)
{
if(x + 200 <= rightBound) {
x = x+200;
}
else {
x = x-200;
}
}
else if(document.getElementById("purple").style.top+(size*120) > y
&& document.getElementById("purple").style.top-(size*20) < y)
{
if(y+200 <= bottomBound) {
y = y+200;
}
else {
y = y-200;
}
}
document.getElementById("pink").style.left = x+"px";
document.getElementById("pink").style.top = y+"px";
The size variable modifies the circle size by a percentage. The default circle size is 100 pixels, but in my code I specify 120 pixels to leave a bit of extra room.
The rightBound and bottomBound variables dictate the bounds in which the circle must be randomly positioned. My code checks if moving the circle 200 pixels to the right, or 200 pixels down would still position the circle within the bounds. If so, then this is done, otherwise the circle is moved 200 pixels to the left instead.
By the way, in case it is not clear x and y are the randomly generated values for the position of the pink circle.
With this code, however, I have still experienced instances where the pink and purple circle will overlap. I'm wondering what the problem is with my logic, as in my explanation and thinking I feel that everything should be working fine.
Why not just keep trying new pink circles until you get one that's right? Random numbers are cheap, after all:
http://jsfiddle.net/HVX7d/
while(distance(purple, pink) < 120) {
pink = {
x: int_rand(100, 500),
y: int_rand(100, 500)
};
}
Just use a loop to keep generating new positions for pink until you're sure there are no collisions, using Pythagorean to calculate how far apart the circles are.
Original Answer (incorrectly assumed 100 was a radius):
The issue is that you're specifying 120 in your boundary logic but only moving the circle by 200 when you detect it. That means there's a scenario where the circles originally don't overlap, but when you move them by only 200 you've created an overlap that didn't previously exist.
Change your instances of 200 to 240 and you shouldn't see any more issues.
For example: you have purple at 200, 200 and pink at 310, 200. That's enough to trigger your boundary logic because 310 - 200 is only 110, so you choose to move pink. Let's say you move it up because it's near the bottom boundary, so now it's at 110, 200 and you've created overlap.
I think this should do what you need:
function reposition_check(x, y, rightBound, bottomBound, size, elem) {
var c1_size = 120 * size;
var c2_size = 120 * size;
var c1_x = parseInt(elem.style.left.replace("px", "")) + (c1_size / 2); //center the purple x coordinate
var c1_y = parseInt(elem.style.top.replace("px", "")) + (c1_size / 2); //center the purple y coordinate
var c2_x = x + (c2_size / 2); //center the pink x coordinate
var c2_y = y + (c2_size / 2); //center the pink y coordinate
var d_x = c1_x - c2_x; //distance on the x plane
var d_y = c1_y - c2_y; //distance on the y plane
if (Math.sqrt((d_x * d_x) + (d_y * d_y)) < (c1_size / 2) + (c2_size / 2)) { //Pythagorean theorum to determine if overlapping
console.log("is overlapping");
if (Math.abs(d_x) < (c1_size / 2) + (c2_size / 2)) { //if true, the overlap is on the x plane
//if(x + (c2_size) + 200 <= rightBound && d_x > 0) {
if(d_x > 0) {
x = (x + 200 <= rightBound) ? x + 200 : (x - 200 - d_x);
}else{
x = (x + 200 <= rightBound) ? x - d_x + 200 : (x - 200);
}
return {x: x, y: y};
}
if (Math.abs(d_y) < (c1_size / 2) + (c2_size / 2)) { //if true, the overlap is on the y plane
if(d_y > 0) {
y = (y + 200 <= bottomBound) ? y + 200 : (y - 200 - d_y);
}else{
y = (y + 200 <= bottomBound) ? y - d_y + 200 : (y - 200);
}
return {x: x, y: y};
}
}
return {x: x, y: y};
}
//Here's how you would use it:
var purple = document.getElementById("purple");
var values = reposition_check(111, 1, 1000, 800, 1, purple); //x, y, rightBound, bottomBound, size, element
document.getElementById("pink").style.left = values.x + "px";
document.getElementById("pink").style.top = values.y + "px";

Dragging a rotated element within a certain boundary

In the following fiddle, you can click and drag around the image, and it will not be able to exit the blue border. By clicking the red and green rectangles, you can rotate the image. However when you click and drag a rotated object, the image does not follow the mouse. I would like the image to follow the mouse even if it is rotated.
http://jsfiddle.net/n3Sn5/
I think the issue occurs within my move function
move = function (dx, dy)
{
nowX = Math.min(boundary.attr("x")+boundary.attr("width")-this.attr("width"), this.ox + dx);
nowY = Math.min(boundary.attr("y")+boundary.attr("height")-this.attr("height"), this.oy + dy);
nowX = Math.max(boundary.attr("x"), nowX);
nowY = Math.max(boundary.attr("y"), nowY);
this.attr({x: nowX, y: nowY });
}
One thing to notice is that when you click and drag a rotated object, after you release your mouse click, if you rotate the image, it snaps to where your mouse was when you released the mouse click, even obeying the boundary.
I was able to get the rotated image to drag with the mouse previously, but by adding the boundary rectangle, i had to use a more complex approach.
If anyone has an idea of what I need to change, I would be very grateful!
Thanks!
The required output can be achieved in a bit different way. Please check the fiddle at http://jsfiddle.net/6BbRL/. I have trimmed to code to keep the basic parts for demo.
var paper = Raphael(0, 0, 475, 475),
boxX = 100,
boxY = 100,
boxWidth = 300,
boxHeight = 200,
// EDITED
imgWidth = 50,
imgHeight = 50,
box = paper.rect(boxX, boxY, boxWidth, boxHeight).attr({fill:"#ffffff"}),
// EDITED
html5 = paper.image("http://www.w3.org/html/logo/downloads/HTML5_Badge_512.png",boxX+boxWidth-imgWidth,boxY+boxHeight-imgHeight,imgWidth,imgHeight)
.attr({cursor: "move"}),
elementCounterClockwise = paper.rect(180, 0, 50, 50).attr({fill:"#ff5555", cursor:"pointer"}),
elementClockwise = paper.rect(250, 0, 50, 50).attr({ fill: "#55ff55", cursor: "pointer" }),
boundary = paper.rect(50,50,400,300).attr({stroke: '#3333FF'}),
transform,
// EDITED
xBound = {min: 50 + imgWidth/2, max: 450 - imgWidth/2},
yBound = {min: 50 + imgHeight/2, max: 350 - imgHeight/2};
start = function (x, y) {
// Find min and max values of dx and dy for "html5" element and store them for validating dx and dy in move()
// This is required to impose a rectagular bound on drag movement of "html5" element.
transform = html5.transform();
}
move = function (dx, dy, x, y) {
// To restrict movement of the dragged element, Validate dx and dy before applying below.
// Here, dx and dy are shifts along x and y axes, with respect to drag start position.
// EDITED
var deltaX = x > xBound.max && xBound.max - x || x < xBound.min && xBound.min - x || 0;
deltaY = y > yBound.max && yBound.max - y || y < yBound.min && yBound.min - y || 0;
this.attr({transform: transform + 'T'+ [dx + deltaX, dy + deltaY]});
}
up = function () {
};
html5.drag(move, start, up);
elementClockwise.click(function() {
html5.animate({transform: '...r90'}, 100);
})
elementCounterClockwise.click(function() {
html5.animate({transform: '...r-90'}, 100);
})
Use of '...' to append a transformation to the pre-existing transformation state (Raphael API) is important for the rotational issue. While, for translating the element on drag requires absolute translation, which neglects the rotational state of the element while translating the element.
//EDIT NOTE
Drag bounding is worked on and updated. However, there remains an issue with incorporating the difference between mouse position and image center.
I can help you with your rotation and drag problem, you need to store the rotation and apply it after you have moved the object.
elementClockwise.node.onclick = function()
{
html5.animate({'transform': html5.transform() +'r90'}, 100, onAnimComplete);
}
elementCounterClockwise.node.onclick = function()
{
html5.animate({'transform': html5.transform() +'r-90'}, 100, onAnimComplete);
}
function onAnimComplete(){
default_transform = html5.transform();
}
At present I can't get the boundary to work, but will have a try later.
http://jsfiddle.net/n3Sn5/2/

Find intersection of two lines given a constant slope and changing coordinates

I asked this question earlier but didn't communicated it clearly, so forgive me for the duplicate. This should be better.
I need to figure the position of a coordinate, given three other coordinates and 2 slopes. Basically, the intersection point of two lines. However, I don't have all of the information normally available to solve this.
I have an arbitrary shape defined by a bunch of vertices. The user may drag a line between these vertices and the shape should react as the diagrams below show.
So in the first example, the user drags line EF from the position on the left to the position on the right (line E2F2). What needs to happen is that line EF grows/shrinks such that it's slope stays the same and that it's beginning and ending coordinates remain on the lines DE and AF respectively. This is shown as line E2F2.
This needs to be generic enough that it can handle any sort of strange or regular angles I throw at it. The second set of shapes shows a simpler approach. The user drags line CD to the position of C2D2. Notice how the slopes stay the same and D2 essentially slides down that diagonal line and B2C2 and C2D2 both extend in length. The result is that all 3 slopes stay the same but lines B2C2 and C2D2 grow in length to stay connected, while line D2E2 shrinks.
You'll need to understand that when dragging line EF, you're actually moving the coordinate "E". So, figuring the first coordinate is easy. And the previous and next one's never change. So I essentially have the slopes of the 3 relevant lines and 3 of the 4 necessary coordinates. I need the 4th, so in my example, F2 or D2.
This code is called on an event every time the coordinate moves. Lets say we're dragging line EF - the coordinate is E then.
var next = this.model.get("next"), // coordinate F
nextNext = next.get("next"), // coordinate A
nextDx = nextNext.get("x") - next.get("x"), // delta X of AF
nextDy = nextNext.get("y") - next.get("y"), // delta Y of AF
prev = this.model.get("prev"), // coordinate D
prevDx = prev.get("x") - this.model.get("x"), // delta X of DF
prevDy = prev.get("y") - this.model.get("y"), // delta Y of DF
selfDx = next.get("x") - this.model.get("x"), // delta X of EF
selfDy = next.get("y") - this.model.get("y"), // delta Y of EF
selfX = this.initialCoords.x + this.shape.getX(), // the new position of E
selfY = this.initialCoords.y + this.shape.getY(),
selfM, selfB, prevM, prevB, nextM, nextB, m, x, y, b;
// check for would-be infinities
if (selfDx == 0) {
// **** THIS WHOLE BLOCK IS CORRECT ****
// i'm vertical
// we can safely assume prev/next aren't also vertical. i think? right?
prevM = prev.get("slope");
prevB = prev.get("y") - prevM * prev.get("x");
var myX = selfX,
myY = prevM * myX + prevB;
this.model.set({
x: myX,
y: myY
});
nextM = next.get("slope");
nextB = next.get("y") - nextM * next.get("x");
var nextX = selfX,
nextY = nextM * nextX + nextB;
next.set({
x: nextX,
y: nextY
});
} else if (selfDy == 0) {
//***** THIS WHOLE BLOCK IS CORRECT **** //
// i'm horizontal
if (prevDx == 0) {
// prev is a vertical line
this.model.set({
y: selfY
});
} else {
prevM = prev.get("slope");
prevB = prev.get("y") - prevM * prev.get("x");
var myY = selfY,
myX = (selfY - prevB) / prevM;
this.model.set({
x: myX,
y: myY
});
}
if (nextDx == 0) {
// next is a vertical line
next.set({
y: selfY
});
} else {
nextM = next.get("slope");
nextB = next.get("y") - nextM * next.get("x");
var nextY = selfY,
nextX = (selfY - nextB) / nextM;
next.set({
x: nextX,
y: nextY
});
}
} else {
// HELP HERE - you've chosen to drag an arbitrarily angled line. Figure out the "next" coordinate given the "current" one.
selfM = this.model.get("slope");
selfB = this.model.get("y") - this.model.get("slope") * this.model.get("x");
if (selfM < 0) {
prevM = prev.get("slope");
prevB = prev.get("y") - prevM * prev.get("x");
var myY = selfY,
myX = (selfY - prevB) / prevM;
// CORRECT, but need "next" position based on this
this.model.set({
x: myX,
y: myY
});
} else {
// CORRECT but need "next" position based on this.
var myX = selfX;
this.model.set({
x: myX
});
}
}
I had a similar situation and had some success using this page as reference :
http://en.wikipedia.org/wiki/Line-line_intersection
You should be able to enumerate all your lines testing for any points where they cross your moving line. These will be the new coordinates.
The equations in the wiki article assume lines of infinite length which you should be aware of but should actually be what you want (I think - there are probably edge cases).

HTML5 Canvas: Splitting/Calculating Lines

I've been banging my head on the keyboard for about one week now and I can't figure a proper solution for my problem. I think it's more Math related than HTML Canvas... hopefully someone can point me into the right direction.
I'm having an HTML Canvas where users can draw lines using they mouse and the very simple moveTo() and lineTo() functions. When the user is done I save the coords in a MongoDB. When the user hits the page later again I want to display his drawing BUT I don't want to load the entire picture with all stored coordinates at once, I want to return it in tiles (for better performance by caching each tile).
The tiles are 200x200 pixels (fixed offsets and width, starting at 0 -> 200-> 400 ->...).
Now, when the user draws a line from let's say 50,50(x/y) to 250,250(x/y) there's only one dot in each bounding box (tile). I need to split the lines and calculate the start and ending points of each line in each bounding box (tile). Otherwise I can't draw the image partially (in tiles). It get's even more complicated when a single line crosses multiple bounding boxes (tiles). For instance: 100,100 (x/y) -> -1234,-300 (x/y).
The lines can go from any point (+/-) to ANY direction for ANY distance.
Of course I looked at Bresenham's good old algorithm and it worked - partially, but it seems like the longest and most resource-hungry solution to me.
So, the reason I'm here is that I hope someone can point me into the right direction with (perhaps) another approach of calculating the start/ending points of my lines for each bounding box.
Code examples are very welcome in JavaScript or PHP.
Thank you for reading and thinking about it :)
tl;dr: Use planes, maths explained below. There's a canvas example at the bottom.
Given that all of your cells are axis-aligned bounding boxes, you could use the plane equation to find the intersection of your line with the edges.
Planes
You can think of your box as a set of four geometric planes. Each plane has a normal, or a vector of length one, indicating which direction is the "front" of the plane. The normals for the planes that make up your cell's sides would be:
top = {x: 0, y: -1};
bottom = {x: 0, y: 1};
left = {x: -1, y: 0};
right = {x: 1, y: 0};
Given a point on the plane, the plane has the equation:
distance = (normal.x * point.x) + (normal.y * point.y)
You can use this equation to calculate the distance of the plane. In this case, you know the top-left corner of your box (let's say x is 10 and y is 100) is on the top plane, so you can do:
distance = (0 * 10) + (-1 * 100)
distance = -100
Checking a point against a plane
Once you have the distance, you can reuse the equation to check where any point is, relative to the plane. For a random point p (where x is -50 and y is 90), you can do:
result = (normal.x * p.x) + (normal.y * p.y) - distance
result = (0 * -50) + (-1 * 90) - (-100)
result = 0 + (-90) - (-100)
result = -90 + 100
result = 10
There are two possible results:
if (result >= 0) {
// point is in front of the plane, or coplanar.
// zero means it is coplanar, but we don't need to distinguish.
} else {
// point is behind the plane
}
Checking a line against a plane
You can check both endpoints of a line from a to b in this way:
result1 = (normal.x * a.x) + (normal.y * a.y) - distance
result2 = (normal.x * b.x) + (normal.y * b.y) - distance
There are four possible results:
if (result1 >= 0 && result2 >= 0) {
// the line is completely in front of the plane
} else if (result1 < 0 && result2 < 0) {
// the line is completely behind the plane
} else if (result1 >= 0 && result2 < 0) {
// a is in front, but b is behind, line is entering the plane
} else if (result1 < 0 && result2 >= 0) {
// a is behind, but b is in front, line is exiting the plane
}
When the line intersects the plane, you want to find the point of intersection. It helps to think of a line in vector terms:
a + t * (b - a)
If t == 0, you are at the start of the line, and t == 1 is the end of the line. In this context, you can calculate the point of intersection as:
time = result1 / (result1 - result2)
And the point of intersection as:
hit.x = a.x + (b.x - a.x) * time
hit.y = a.y + (b.y - a.y) * time
Checking a line against the box
With that math, you can figure out the lines of intersection with your box. You just need to test the endpoints of your line against each plane, and find the minimum and maximum values of time.
Because your box is a convex polygon, there is an early out in this check: if the line is completely in front of any one plane in your box, it cannot intersect with your box. You can skip checking the rest of the planes.
In JavaScript, your result might look something like this:
/**
* Find the points where a line intersects a box.
*
* #param a Start point for the line.
* #param b End point for the line.
* #param tl Top left of the box.
* #param br Bottom right of the box.
* #return Object {nearTime, farTime, nearHit, farHit}, or false.
*/
function intersectLineBox(a, b, tl, br) {
var nearestTime = -Infinity;
var furthestTime = Infinity;
var planes = [
{nx: 0, ny: -1, dist: -tl.y}, // top
{nx: 0, ny: 1, dist: br.y}, // bottom
{nx: -1, ny: 0, dist: -tl.x}, // left
{nx: 1, ny: 0, dist: br.x} // right
];
for (var i = 0; i < 4; ++i) {
var plane = planes[i];
var nearDist = (plane.nx * a.x + plane.ny * a.y) - plane.dist;
var farDist = (plane.nx * b.x + plane.ny * b.y) - plane.dist;
if (nearDist >= 0 && farDist >= 0) {
// both are in front of the plane, line doesn't hit box
return false;
} else if (nearDist < 0 && farDist < 0) {
// both are behind the plane
continue;
} else {
var time = nearDist / (nearDist - farDist);
if (nearDist >= farDist) {
// entering the plane
if (time > nearestTime) {
nearestTime = time;
}
} else {
// exiting the plane
if (time < furthestTime) {
furthestTime = time;
}
}
}
}
if (furthestTime < nearestTime) {
return false;
}
return {
nearTime: nearestTime,
farTime: furthestTime,
nearHit: {
x: a.x + (b.x - a.x) * nearestTime,
y: a.y + (b.y - a.y) * nearestTime
},
farHit: {
x: a.x + (b.x - a.x) * furthestTime,
y: a.y + (b.y - a.y) * furthestTime
}
};
}
If this is still too slow, you can also do broadphase culling by dividing the world up into big rects, and assigning lines to those rects. If your line and cell aren't in the same rect, they don't collide.
I've uploaded a canvas example of this.
This looks like you'd have to figure out at what point each line intersects with the bounds of each tile.
Check out the answer to this question: Is there an easy way to detect line segment intersections?
The answers don't provide code, but it shouldn't be too hard to convert the equations to PHP or Javascript...
EDIT:
Why, exactly, do you want to split the lines? I understand you don't want to load all the lines at once, since that could take a while. But what's wrong with just loading and drawing the first few lines, and drawing the remainder later on?
Methinks that would be a lot simpler than having to cut up each line to fit in a specific tile. Tiling is a nice way of optimizing bitmap loading; I don't think it's very appropriate for vector-based drawings.
You could also consider sending an Ajax request, and start drawing the whole thing whenever it comes in; this would not interfere with the loading of the page.

Categories

Resources