• ベストアンサー
  • 暇なときにでも

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

  • 質問No.5620787
  • 閲覧数84
  • ありがとう数3
  • 回答数2

お礼率 100% (3/3)

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

こんにちは、図の赤い点をマウスでライン上で移動させるにはどう計算すればよろしいのでしょうか。
図の左では x 値を利用すればなんとなくできますが、右の図になるとかなり上のほうに飛んでってしまいます。
また y 値を利用しても同様のことが起こると思います。

正確にライン上にマウスがある場合のみに操作するとかなり使い勝手が悪くなってしまい、ある程度は遊び ? がないとダメだと思います。

どのように考えればよろしいのでしょうか。

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

  • 回答No.2
  • ベストアンサー

ベストアンサー率 52% (430/816)

要は点(マウスカーソル)と直線を最短距離で結び、その交点を求めたいという事でしょうか?

であるならマウスカーソルのポイントを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

お礼率 100% (3/3)

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

その他の回答 (全1件)

  • 回答No.1

ベストアンサー率 25% (1/4)

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

外してたらごめんなさい。
お礼コメント
yakionigiriX

お礼率 100% (3/3)

レスありがとうございます。
円の半径を使うのは気がつきませんでした。
方法の幅が広がります。
いろいろ試行錯誤してみます。
投稿日時:2010/01/26 00:13
関連するQ&A

その他の関連するQ&Aをキーワードで探す

ピックアップ

ページ先頭へ