Archive for the 'NSPointInRect' Category

2017/03/05 矩形座標同士の衝突判定 v2

2つのNSRect同士の衝突判定を行うAppleScriptです。v1ではNSRectの内含の順序が異なると衝突を検出できないので修正しました。

→ 矩形座標同士の衝突判定 v3

rect2_resized.png

Rect AがRect Bを含むかどうかチェックを行うというのがV1の処理内容で、これはRect AがRect Bよりも大きいことを前提としたもの。Rect Bのほうが大きい場合には成立しません。

そこで、Rect A>Rect Bを前提とした処理を行なったあとで、衝突していない(false)と判定した場合には、Rect AとRect Bを入れ替えて再度処理してみました。最悪の場合、かなりの回数のループを行なってしまうわけですが、他にいろいろ解決策はありそうです。

救いがあるのは、数百回程度のループ処理ならさほど時間がかからないというところでしょうか。1対の矩形の衝突判定で0.01秒程度。座標のステップ値を10に設定したときには0.002秒程度でした。

AppleScript名:矩形座標同士の衝突判定 v2
– Created 2017-03-05 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4510

set a1Rect to {origin:{x:10, y:10}, |size|:{width:100, height:100}}
set b1Rect to {origin:{x:30, y:30}, |size|:{width:100, height:100}}
set a1Res to detectCollision(a1Rect, b1Rect, 1) of me
–> true

set a2Rect to {origin:{x:10, y:10}, |size|:{width:100, height:100}}
set b2Rect to {origin:{x:200, y:30}, |size|:{width:100, height:100}}
set a2Res to detectCollision(a2Rect, b2Rect, 1) of me
–> false

set a3Rect to {origin:{x:30, y:30}, |size|:{width:50, height:50}}
set b3Rect to {origin:{x:10, y:10}, |size|:{width:100, height:100}}
set a3Res to detectCollision(a3Rect, b3Rect, 1) of me
–> true

set a4Rect to {origin:{x:0, y:20}, |size|:{width:100, height:10}}
set b4Rect to {origin:{x:10, y:10}, |size|:{width:50, height:100}}
set a4Res to detectCollision(a4Rect, b4Rect, 1) of me
–> true

–NSRect同士の衝突判定
on detectCollision(aRect, bRect, stepNum)
  set a1Res to detectCollisionSub(aRect, bRect, stepNum) of me
  
if a1Res = true then
    return true
  else
    set a2Res to detectCollisionSub(bRect, aRect, stepNum) of me
    
return a2Res
  end if
end detectCollision

on detectCollisionSub(aRect, bRect, stepNum)
  
  
set origX1 to aRect’s origin’s x
  
set origY1 to aRect’s origin’s y
  
set origX2 to origX1 + (aRect’s |size|’s width)
  
set origY2 to origY1 + (aRect’s |size|’s height)
  
  
repeat with i from origX1 to origX2 by stepNum
    set aPoint to {x:i, y:origY1}
    
set aRes to current application’s NSPointInRect(aPoint, bRect)
    
if aRes = true then return true
  end repeat
  
  
repeat with i from origY1 to origY2 by stepNum
    set aPoint to {x:origX2, y:i}
    
set aRes to current application’s NSPointInRect(aPoint, bRect)
    
if aRes = true then return true
  end repeat
  
  
repeat with i from origX1 to origX2 by stepNum
    set aPoint to {x:i, y:origY2}
    
set aRes to current application’s NSPointInRect(aPoint, bRect)
    
if aRes = true then return true
  end repeat
  
  
repeat with i from origY1 to origY2 by stepNum
    set aPoint to {x:origX1, y:i}
    
set aRes to current application’s NSPointInRect(aPoint, bRect)
    
if aRes = true then return true
  end repeat
  
  
return false
end detectCollisionSub

★Click Here to Open This Script 

2017/03/05 矩形座標同士の衝突判定

2つのNSRect同士の衝突判定を行うAppleScriptです。

→ 矩形座標同士の衝突判定 v3

NSRect(矩形)とNSPoint(点)の間で矩形に座標が含まれるかどうか確認を行うのには、NSPointInRectを利用することになりますが、Referenceを見てもNSRect(矩形)同士が重なっているかどうかを確認するメソッドが存在しないようです。

矩形同士の衝突判定を行う仕組みといえばSpriteが存在しているため、SpriteKitの機能を使えば簡単にできそうですが、そこまで手をかけなくても、ただ単にNSRect(矩形)の外周部を1刻みでNSPoint(点)に分解し、すべてのNSPoint(点)が相手側のNSPoint(矩形)に含まれるかをループでチェックすればわかります(知性のカケラもない処理です)。

rect1_resized.png

大きな矩形同士であれば、ステップ数を大きくするなどのチューニングも必要かもしれませんが、ほかにもっといい手段がありそうな気もします。

AppleScript名:矩形座標同士の衝突判定
– Created 2017-03-05 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4508

set a1Rect to {origin:{x:10, y:10}, |size|:{width:100, height:100}}
set b1Rect to {origin:{x:30, y:30}, |size|:{width:100, height:100}}
set a1Res to detectCollisionDetect(a1Rect, b1Rect, 1) of me
–> true

set a2Rect to {origin:{x:10, y:10}, |size|:{width:100, height:100}}
set b2Rect to {origin:{x:200, y:30}, |size|:{width:100, height:100}}
set a2Res to detectCollisionDetect(a2Rect, b2Rect, 1) of me
–> false

–NSRect同士の衝突判定
on detectCollisionDetect(aRect, bRect, stepNum)
  
  
set origX1 to aRect’s origin’s x
  
set origY1 to aRect’s origin’s y
  
set origX2 to origX1 + (aRect’s |size|’s width)
  
set origY2 to origY1 + (aRect’s |size|’s height)
  
  
repeat with i from origX1 to origX2 by stepNum
    set aPoint to {x:i, y:origY1}
    
set aRes to current application’s NSPointInRect(aPoint, bRect)
    
if aRes = true then return true
  end repeat
  
  
repeat with i from origY1 to origY2 by stepNum
    set aPoint to {x:origX2, y:i}
    
set aRes to current application’s NSPointInRect(aPoint, bRect)
    
if aRes = true then return true
  end repeat
  
  
repeat with i from origX1 to origX2 by stepNum
    set aPoint to {x:i, y:origY2}
    
set aRes to current application’s NSPointInRect(aPoint, bRect)
    
if aRes = true then return true
  end repeat
  
  
repeat with i from origY1 to origY2 by stepNum
    set aPoint to {x:origX1, y:i}
    
set aRes to current application’s NSPointInRect(aPoint, bRect)
    
if aRes = true then return true
  end repeat
  
  
return false
end detectCollisionDetect

★Click Here to Open This Script