• ベストアンサー

ライン上のカーソル移動させるには

ライン上のカーソル移動させるには こんにちは、図の赤い点をマウスでライン上で移動させるにはどう計算すればよろしいのでしょうか。 図の左では x 値を利用すればなんとなくできますが、右の図になるとかなり上のほうに飛んでってしまいます。 また y 値を利用しても同様のことが起こると思います。 正確にライン上にマウスがある場合のみに操作するとかなり使い勝手が悪くなってしまい、ある程度は遊び ? がないとダメだと思います。 どのように考えればよろしいのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.2

要は点(マウスカーソル)と直線を最短距離で結び、その交点を求めたいという事でしょうか? であるならマウスカーソルのポイントをP(x0,y0)とします。 まず直線A(m1*x+n1)に直交し、Pを通る直線B(m2*x+n2)の傾きm2を求めます。 m2 = -1 / m1; BはPを通るので y0 = m2*x0 + n2→n2 = y0 - m2*x0 これで直線Bが求まりました。 AとBの交点(x1,y1)を求めます。 m1*x1+n1 = m2*x1+n2→x1 = (n2 - n1) / (m1 - m2) y1 = m1 * x1 + n1 やっつけですがサンプルを作ってみました。(線上の赤い点がマウスカーソルにあわせて移動します) LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {   static HPEN red_pen = CreatePen( PS_SOLID , 2 , RGB(255,0,0) );   static POINT last_point;   static POINT point_on_line;   PAINTSTRUCT ps;   HDC hdc;   switch (message)   {   case WM_PAINT:     hdc = BeginPaint(hWnd, &ps);     MoveToEx( hdc , 0 , 50 , NULL );     LineTo( hdc , 640 , 480 + 50 );     SelectObject( hdc , red_pen );     Ellipse( hdc , point_on_line.x - 3 , point_on_line.y -3 , point_on_line.x + 3 , point_on_line.y + 3 );     EndPaint(hWnd, &ps);     break;   case WM_MOUSEMOVE:     {       double x0 = (double)LOWORD(lParam);       double y0 = (double)HIWORD(lParam);       double n1 = 50.0f;       double m1 = 480.0 / 640.0;       double m2 = -1.0 / m1;       double n2 = y0 - m2*x0;       double x1 = (n2 - n1) / (m1 - m2);       double y1 = m1 * x1 + n1;       point_on_line.x = (int)x1;       point_on_line.y = (int)y1;       InvalidateRect( hWnd , NULL , TRUE );     }     break;   case WM_DESTROY:     PostQuitMessage(0);     break;   default:     return DefWindowProc(hWnd, message, wParam, lParam);   }   return 0; } 「遊び」に関しては (x0,y0)と(x1,y1)の距離から判定すれば良いと思います。

yakionigiriX
質問者

お礼

わざわざサンプルを作っていただきありがとうございます。 プログラムが下手なのでちょっと挙動がおかしいですが、 それらしいものはできました。とても参考になりました。 ありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (1)

  • ken2r
  • ベストアンサー率25% (1/4)
回答No.1

図の意味が少し理解できなかったのですが、 マウスのイベントで座標が分かりますよね。 次にその座標が直線上にあるかどうかの判定ができればいい訳だから 円の半径を「遊び」にして 直線の円の交差の有無で判定してはどうでしょうか? 外してたらごめんなさい。

yakionigiriX
質問者

お礼

レスありがとうございます。 円の半径を使うのは気がつきませんでした。 方法の幅が広がります。 いろいろ試行錯誤してみます。

すると、全ての回答が全文表示されます。

関連するQ&A