Question

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.

enter image description here

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
                });
            }
        }
Was it helpful?

Solution

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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top