2013-04-29 61 views
1

我之前問過這個問題,但沒有清楚地傳達它,所以請原諒我的重複。這應該會更好。找到兩條線的交叉點,給定一個不變的斜率並改變座標

我需要計算一個座標的位置,給出其他三個座標和兩個斜率。基本上,兩條線的交點。但是,我並沒有獲得解決此問題的所有信息。

我有一堆頂點定義的任意形狀。用戶可以在這些頂點之間拖動一條線,形狀應該如下圖所示的那樣反應。

因此,在第一個示例中,用戶將EF線從左邊的位置拖動到右邊的位置(線E2F2)。需要發生的是EF線的增長/收縮,使得它的斜率保持不變,並且它的開始和結束座標分別保留在線DE和AF上。這顯示爲線E2F2。

這需要足夠通用,它可以處理任何類型的奇怪或常規角度我扔在它。第二組形狀顯示更簡單的方法。用戶將行CD拖到C2D2的位置。注意斜坡是如何保持不變的,D2基本上沿着對角線向下滑動,B2C2和C2D2的長度都是相同的。結果是所有3個斜坡保持不變,但是線B2C2和C2D2長度保持連接,而線D2E2縮小。

enter image description here

你要明白,拖線EF的時候,你實際上是移動的座標「E」。所以,確定第一個座標很容易。上一個和下一個永遠不會改變。所以我基本上有3條相關線的斜率和4個必要座標中的3個。我需要第四,所以在我的例子中,F2或D2。

每次座標移動時,都會在事件上調用此代碼。假設我們正在拖動EF線 - 那麼座標是E。

  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 
       }); 
      } 
     } 

回答

0

我也有類似的情況,不得不使用此頁面作爲參考一些成功: http://en.wikipedia.org/wiki/Line-line_intersection

你應該能夠列舉了它們交叉的動線的任何點所有線路的測試。這些將是新的座標。

維基文章中的方程式假定行數無限長,您應該知道,但實際上應該是您想要的(我認爲 - 有可能是邊緣案例)。

+0

我把它運用到了最後 - 這是永久的)使用該公式,但從一個不同的網站和一些幫助代碼來完成繁重的工作。但是,我會將你的標記作爲答案。只需要一些JS的擺弄工作就可以了。 – oooyaya 2013-04-29 19:32:45

+0

謝謝!只是認爲它可能會指向你正確的方向 - 很高興聽到你把它分類。 – 2013-04-29 20:55:16

+0

@oooyaya你能分享你的JS,救我重塑輪子嗎?謝謝! – Tiago 2017-12-14 10:47:12