HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2009
1130
山本線分とボックスの判定5未解決


山本

リンク

2009/11/30(Mon) 20:16:38|NO.29079

HSPで、線分(x1,y1 - x2,y2)と長方形・ボックス(x1,y1,x2,y2)の交差判定をとるにはどのようにしたら良いでしょうか?

交点を求める必要はなく、とにかく速度重視であるものを想定しています。
自分でもgoogleを駆使して色々チャレンジしてみたのですが、良い方法が見つかりませんでした・・・

知恵をお持ちの方がいらっしゃいましたら、お力を貸していただきたいです。



この記事に返信する


KA

リンク

2009/11/30(Mon) 21:57:02|NO.29080

まず質問するときは、良く考えて下さい。

>>HSPで、線分(x1,y1 - x2,y2)と長方形・ボックス(x1,y1,x2,y2)の交差判定を・・・
>>交点を求める必要はなく、とにかく速度重視であるものを想定しています。
 →”交差判定””交点”、要は”重なりを判定したい”のでしょうか?

>>自分でもgoogleを駆使して色々チャレンジしてみたのですが、良い方法が・・・
 →まず、どう駆使(探して?)してダメだったのか、分かりません。

どういうスクリプトがダメで、どうしたいのかハッキリさせたほうが、回答も得られやすい
でしょう。



woodfields

リンク

2009/11/30(Mon) 23:40:13|NO.29084

座標計算とかメンドなので、塗りつぶしと座標のカラー取得でどうでしょうか


x_1=10 ; 線分座標 y_1=20 x_2=300 y_2=300 x1=100 ; ボックス座標 y1=100 x2=200 y2=200 ;①と長方形・ボックス(x1,y1,x2,y2)をたとえばRGB(0,0,0)boxfで描画して、 ;線分の始終点x_1,y_1、x_2,y_2の2点がRGB(0,0,0)なら交わってる color 0,0,0 ; ボックス色 boxf x1,y1,x2,y2 ; ボックス pget x_1,y_1 : if ginfo_r == 0 : dialog "アタリ!" : stop pget x_2,y_2 : if ginfo_r == 0 : dialog "アタリ!" : stop ;②線分(x_1,y_1 - x_2,y_2)をたとえばRGB(0,0,255)で描画してから、 ;x1,y1から閉塞領域を任意のブラシ色で塗りつぶして、;x1,y2、x2,y1、x2,y2の3点をpget命令で取得し、ひとつでも塗りつぶし色(ブラシ色)でなければ交わってる。 #uselib "gdi32.dll" #func GetPixel "GetPixel" sptr,sptr,sptr ; HDC hdc, デバイスコンテキストのハンドル ; int nXPos, ピクセルの x 座標 ; int nYPos ピクセルの y 座標 #func CreateSolidBrush "CreateSolidBrush" sptr ; COLORREF crColor ブラシの色を表す値 #func SelectObject "SelectObject" sptr,sptr ; HDC hdc, デバイスコンテキストのハンドル ; HGDIOBJ hgdiobj オブジェクトのハンドル #func ExtFloodFill "ExtFloodFill" sptr,sptr,sptr,sptr,sptr ; HDC hdc, デバイスコンテキストのハンドル ; int nXStart, 開始点の x 座標 ; int nYStart, 開始点の y 座標 ; COLORREF crColor 塗りつぶしの色 ; UINT fuFillType 塗りつぶしの種類 ;#const FLOODFILLBORDER $00000000 #const FLOODFILLSURFACE $00000001 #func DeleteObject "DeleteObject" int ; HGDIOBJ hObject グラフィックオブジェクトのハンドル #uselib "user32.dll" #func ReleaseDC "ReleaseDC" sptr,sptr ; HWND hWnd, ウィンドウのハンドル ; HDC hDC デバイスコンテキストのハンドル #func InvalidateRect "InvalidateRect" int,int,int ; HWND hWnd, ウィンドウのハンドル ; CONST RECT *lpRect, 長方形の座標 ; BOOL bErase 消去するかどうかの状態 color 0,0,255 ; 線分色 line x_1,y_1,x_2,y_2 ; 線分 color 255,0,0 ; ブラシ色 ; ブラシ色 GetPixel hdc,x1,y1 : colref=stat ;BMSCR構造体にセットされている色を使いブラシを作成 mref bmscr,67 CreateSolidBrush bmscr(40) : ahBrush=stat SelectObject hdc,ahBrush : ahOldBrush=stat ;閉塞領域に描画されている色と新規に塗る色とを比較して違うならば新規の色を塗る ExtFloodFill hdc,x1,y1,colref,0 : ret=stat if ret!1 { ExtFloodFill hdc,x1,y1,colref,FLOODFILLSURFACE } SelectObject hdc,ahOldBrush DeleteObject ahBrush ReleaseDC hwnd,hdc InvalidateRect hwnd,0,1 ; 再描画 color 0,0,0 pget x1,y2 : if ginfo_r != 255 : dialog "アタリ!" : stop pget x2,y1 : if ginfo_r != 255 : dialog "アタリ!" : stop pget x2,y2 : if ginfo_r != 255 : dialog "アタリ!" : stop



.Hrk

リンク

2009/12/1(Tue) 09:45:14|NO.29093

これとかどうでしょう?昔作ったものですが、見た感じうまく動いているように思います。
参考までにどうぞ。

HSPソース
http://zero.nthock.harisen.jp/test/HitTest_l2s/HitTest_l2s_m2.hsp

実行ファイル
http://zero.nthock.harisen.jp/test/HitTest_l2s/HitTest_l2s_m2.exe



GENKI

リンク

2009/12/1(Tue) 23:25:05|NO.29106

開発wikiに関連記事がいくつかあります。
例:http://hspdev-wiki.net/?%BE%D7%C6%CD%C8%BD%C4%EA#md52a044
小ワザのゲーム関連の項目も探してみてください。



shinkun

リンク

2009/12/2(Wed) 21:09:43|NO.29114

すでに良い回答が出ているみたいですが、せっかく作ったので載せますね。

; ------------------------------------------------------------------------------ ; 線分 と 矩形 の交差判定 ; programmed by shinkun. ; 2009/12/1 #module ; -------------------------------------------------------------------------- ; _IsCross(x,y,x1,y1,x2,y2) ; 線分が矩形の対角線のひとつと交差しているかどうかを返す。 ; 引数 ; x, y - 線分の端点のひとつを原点Oとした時の、もう一方の端点の座標 ; x1, y1 - 線分の端点のひとつを原点Oとした時の、矩形の対角線の点①の座標 ; x2, y2 - 線分の端点のひとつを原点Oとした時の、矩形の対角線の点②の座標 ; 戻り値 ; 1 - 線分と対角線は交差している ; 0 - 線分と対角線は交差していない ; 補足 ; この関数では、線分の端点のひとつを原点とする座標系で考える。 #defcfunc _IsCross int x, int y, int x1, int y1, int x2, int y2, local a, local b ; 線分と矩形の対角線が交差しているかどうかの判定 b = x1 * y2 - x2 * y1 ; 分母の計算 if (b == 0): return 0 a = double(x * y2 - x2 * y) / b b = double(x * y1 - x1 * y) / -b return (a >= 0.0) && (b >= 0.0) && (a + b >= 1.0) ; この計算の元となる考え方は次の通り。 ; ①線分の端点をそれぞれAとBとする。また、矩形の2つある対角線の内 ; ひとつを選び、その端点をCとDとする。 ; ②ベクトルAC、ADを使って、ベクトルABを表す方程式 ; AB=αAC+βAD (α,βは実数) ; を考える。すると、α≧0, β≧0, α+β=1 の時、点Bは対角線CD ; 上に乗っている事になるので、α + β >= 1 だと線分ABは対角線を ; 交差するという事になる。 ; ③よって、方程式を x 座標, y 座標でそれぞれ分解して連立方程式とし、 ; αとβを解くと上記の計算式となる。 ; -------------------------------------------------------------------------- ; IsOverlappedPointToRect(px,py,rx,ry,rw,rh) ; (px,py) の点が、(x,y) を左上とし幅 w, 高さ h の矩形内にあるかどうかを ; 返す。 ; 引数 ; px, py - 点の座標 ; rx, ry - 矩形の左上座標 ; rw, rh - 矩形の幅と高さ ; 戻り値 ; 1 - 点は矩形内にある ; 0 - 点は矩形内にない #defcfunc IsOverlappedPointToRect int px, int py, int x, int y, int w, int h if (px < x): return 0 if (py < y): return 0 if (px >= x + w): return 0 if (py >= y + h): return 0 return 1 ; -------------------------------------------------------------------------- ; IsOverlappedSegmentToRect(x1,y1,x2,y2,x,y,w,h) ; (x1,y1), (x2,y2) で結ばれる線分と (x,y) を左上とし幅 w, 高さ h の矩形が ; 重なっているかどうかを返す。 ; 引数 ; x1, y1 - 線分の端点① ; x2, y2 - 線分の端点② ; x, y - 矩形の左上座標 ; w, h - 矩形の幅と高さ ; 戻り値 ; 1 - 線分と矩形は交差している ; 0 - 線分と矩形は交差していない #defcfunc IsOverlappedSegmentToRect int x1, int y1, int x2, int y2, int x, int y, int w, int h ; 線分の端点が矩形内に存在するかどうかを調べる if (IsOverlappedPointToRect(x1,y1,x,y,w,h)): return 1 if (IsOverlappedPointToRect(x2,y2,x,y,w,h)): return 1 ; ここで検出されるのは、矩形内に ①線分の両端、②線分の一方の端点 が ; 存在する場合である。これ以降は、線分の端点が矩形外にある場合を取り ; 扱う。つまり、①両端とも矩形内には存在しないが、その両端を結ぶ線分 ; が矩形上を通過する場合 ②線分も完全に矩形を外れている場合 である。 ; 線分が矩形内に存在するかどうかを調べる if (_IsCross(x2-x1,y2-y1,x-x1,y+h-y1,x+w-x1,y-y1)): return 1 if (_IsCross(x2-x1,y2-y1,x-x1,y-y1,x+w-x1,y+h-y1)): return 1 return 0 #global ; 定数定義 #const KEYCODE_LCLICK 1 ; 左クリックのキーコード #const KEYCODE_RCLICK 2 ; 右クリックのキーコード *start ; 変数定義 rect = 200, 200, 240, 80 ; 矩形の x, y 座標と幅と高さ pt1 = 100, 50 ; 線分の端点① (x,y) pt2 = 540, 50 ; 線分の端点② (x,y) result = 0 ; 交差判定の結果 ; タイトル設定 title "左・右クリックで線分の端点①・②を移動" *main gosub *update gosub *output await 20 goto *main *update ; クリック検出&移動 getkey isClick, KEYCODE_LCLICK if (isClick): pt1 = mousex, mousey getkey isClick, KEYCODE_RCLICK if (isClick): pt2 = mousex, mousey ; 線分と矩形の交差判定 result = IsOverlappedSegmentToRect(pt1(0),pt1(1),pt2(0),pt2(1),rect(0),rect(1),rect(2),rect(3)) return *output ; 描画反映禁止 redraw 0 ; 画面クリア color 255, 255, 255 boxf ; 矩形描画 color 204, 204, 240 boxf rect(0), rect(1), rect(2)+rect(0)-1, rect(3)+rect(1)-1 ; 線分描画 color 0, 0, 0 line pt2(0), pt2(1), pt1(0), pt1(1) pos pt1(0), pt1(1): mes "①" pos pt2(0), pt2(1): mes "②" ; 交差判定の結果を描画 pos 0, 0 if (result) { mes "判定結果: 交差している" } else { mes "判定結果: 交差していない" } ; 描画反映 redraw 1 return



ONION software Copyright 1997-2025(c) All rights reserved.