2017-07-28 4 views
0

swiftで関数を記述しようとしていますが、ベクトルの拡張子(画面内にある)が画面と交差するCGPointを返します。ベクトルが方向(スウィフト)に向かって拡大するとベクトルが交差する場所

func calcPoint(start: CGPoint, end: CGPoint) -> CGPoint 
  • 開始:

    the screen scheme

    機能は、次のパラメータを持っている必要がありますのは、画面がそれはスキームのようなものだ800×600であると仮定しようするCGPoint(X:×1、Y :y1) - これはベクトルの始まりです。

  • end:CGPoint(x:x1、y:y1) - これはベクトルの終点です。
  • リターンポイントは、ベクトルがスクリーン(CGPoint(x:x3、y:y3)と交差するスキームに示されているもの)です。

ベクトルの開始と終了の値は、画面内のポイント(四角形0、0、800、600)です。 (アレクサンダー用)EDIT

: 与えられた状況で、それは簡単に...他の場合には使用していない明白な方法で、機能を書くことになります式が、そこには...と三角形の比率を頂点?

+0

を歓迎しているので、あなたの質問は何ですか? – Alexander

+0

今質問があります。 –

答えて

1

ポイントEを計算するには、設定によって与えられた三角形を見ることができます。あなたは三角形ABCとDBEを持っています。 intercept theorem(ABなどはAとBの間の線分を表す)を使用して、以下の関係ABを設定できるように、それらは似ていることに注意してください。

ケースの開始と終了で

enter image description here

は同じxまたはy軸を持っている:与えられたすべてのポイントを知っているが、与えられた設定から開始点と終了点を使用してE.

enter image description here

設定するには座標は、同じ座標の上下端または左端境界だけです。

絶対値を使用すると、四角形の四隅すべてで有効になります。 AC = D'B:もちろん、あなたはEはあなたの四角形の外にあることを考慮する必要があり、再び同じ関係がAB使用することができ、その後D'E」

enter image description here

+0

あなたは正しいです。残念なことに、この方向に進むには、8つのケースをテストする必要があります。ベクトルが方向に基づいてxまたはyに平行な場合、4つのケースがあり、ベクトルの方向が4つの可能性のある場合 - 他の4つのケースがあります。 –

+0

はい、絶対値を使用するとケースが減少すると思います。理論上、ほとんどの問題には素晴らしい解決策がありますが、実装は常に別の話です。 – gue

+0

あなたの答えは間違いなく正しいです。 1〜2日以内に他の人がいなければそれを受け入れます。私はより良いソリューションを作りようとしています。例えば、ベクトルの始点を座標系の点0,0とすると、角度(0〜360度)と座標系の変換だけが扱われます。 –

0

を単一の式はありませんが、交差点理由開始点の位置、線の傾き、長方形のサイズに依存し、任意の長方形のエッジで発生することがあります。

ここでは、線のパラメトリック表現に基づくアプローチです。任意の斜面(水平と垂直を含む)で動作します。境界が最初に交差しているかどうかを調べ、交差点を計算します。

dx = end.x - start.x 
dy = end.y - start.y 

//parametric equations for reference: 
//x = start.x + dx * t 
//y = start.y + dy * t 

//prerequisites: potential border positions 
if dx > 0 then 
    bx = width 
else 
    bx = 0 

if dy > 0 then 
    by = height 
else 
    by = 0 

//first check for horizontal/vertical lines 
if dx = 0 then 
    return ix = start.x, iy = by 

if dy = 0 then 
    return iy = start.y, ix = bx 


//in general case find parameters of intersection with horizontal and vertical edge 
tx = (bx - start.x)/dx 
ty = (by - start.y)/dy 

//and get intersection for smaller parameter value 
if tx <= ty then 
    ix = bx 
    iy = start.y + tx * dy 
else 
    iy = by 
    ix = start.x + ty * dx 

return ix, iy 
0

な(イボIvanoffのおかげで)に興味を持って皆のための純粋な迅速な解決策:

// Example for iOS 
/// The height of the screen 
let screenHeight = UIScreen.main.bounds.height 
/// The width of the screen 
let screenWidth = UIScreen.main.bounds.width 

func calculateExitPoint(from anchor : CGPoint, to point: CGPoint) -> CGPoint { 
    var exitPoint : CGPoint = CGPoint() 
    let directionV: CGFloat = anchor.y < point.y ? 1 : -1 
    let directionH: CGFloat = anchor.x < point.x ? 1 : -1 
    let a = directionV > 0 ? screenHeight - anchor.y : anchor.y 
    let a1 = directionV > 0 ? point.y - anchor.y : anchor.y - point.y 
    let b1 = directionH > 0 ? point.x - anchor.x : anchor.x - point.x 
    let b = a/(a1/b1) 
    let tgAlpha = b/a 
    let b2 = directionH > 0 ? screenWidth - point.x : point.x 
    let a2 = b2/tgAlpha 
    exitPoint.x = anchor.x + b * directionH 
    exitPoint.y = point.y + a2 * directionV 
    if (exitPoint.x > screenWidth) { 
     exitPoint.x = screenWidth 
    } else if (exitPoint.x < 0) { 
     exitPoint.x = 0; 
    } else { 
     exitPoint.y = directionV > 0 ? screenHeight : 0 
    } 
    return exitPoint 
} 

最適化の任意の種類は;-)

関連する問題