Question

I have a system of vertices with lines connecting them. I measure the angle at each vertex by comparing itself and it's "next" point (the vertices are a doubly linked list).

var next = this.get("next"),
    dX = next.get("x") - this.get("x"),
    dY = next.get("y") - this.get("y"),
    radians = Math.atan2(dY, dX);

When this angle between them hits some threshold, like +/- 2 degrees from a 45 degree... so like 47 degrees and we want to call it 45... I need to move this point to the x,y that would be dictated should it have been 45 degrees. This same thing applies to 135, 90, 180, etc.

I can detect the angle and whether we're within the snap-to-45 zone easy enough, and I know which angle we ought to set it to. What I don't know how to find is the x,y given that new angle.

if(CLOSE_ENOUGH_TO_SNAP) {
    newAngle = Math.round(angle / 45) * 45;

    this.set({
       x: something,
       y: something
    });
}

So in the below image, this angle ought to snap to 90 and so I ought to be able to calculate a new x,y given that it's 90, not 92.

enter image description here

Was it helpful?

Solution

in psuedocode:

point dif = currentPt - previousPt

float distance = sqrt(dif.x * dif.x + dif.y * dif.y)

float newCurrentX = previousPt.x + distance * cos(newAngle)

floar newCurrentY = previousPt.y + distance * sin(newAngle)

However, if all the new angles are multiples of 45, you could avoid using sin and cos.

For a multiple of 90 degress (or zero degrees),

if (newAngle is 90) newCurrentY = previousPt.y + distance 
else if (newAngle is 0) newCurentX = previousPt.x + distance,
 etc.

for multiples of 45 degress:

else if (newAngle is 135) { 
 shift = distance * CONST_SIN_OF_45; 
 newCurrentX = previousPt.x - shift; 
 newCurrentY = previousPt.y + shift; 
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top