2009-05-27 35 views
8

Tôi đang giới thiệu một phần mềm và muốn xây dựng chức năng 'di chuột' của chuột để tôi về cơ bản có thể tự động hóa quy trình. Tôi muốn tạo ra những chuyển động chuột thực tế nhưng có một chút khối tâm trí trong quá trình suy nghĩ. Tôi có thể di chuyển chuột một cách dễ dàng với C# nhưng muốn nó thực tế hơn một chút so với chỉ con trỏ xuất hiện tại một số x, y, tọa độ và sau đó nhấn một nút.C# di chuyển chuột xung quanh thực tế

Tôi nhận được vị trí hiện tại của con chuột và sau đó nhận điểm kết thúc. Tính toán một vòng cung giữa hai điểm, nhưng sau đó tôi cần tính điểm dọc theo vòng cung đó để tôi có thể thêm một sự kiện hẹn giờ vào đó để tôi có thể di chuyển từ điểm này sang điểm tiếp theo, và lặp lại điều này cho đến khi tôi đạt được mục tiêu ...

Có ai muốn xây dựng không?

Cảm ơn, R.

+1

Bạn di chuyển chuột từ điểm A đến điểm B trong cung tròn? Tôi dường như đi theo một đường thẳng. Điều đó sẽ làm cho cuộc sống của bạn dễ dàng hơn nhiều. :) –

+0

Vì vậy, câu hỏi là gì? Xây dựng trên ý tưởng của bạn? – JerSchneid

+0

JP: trừ khi bạn làm việc với một người cai trị là tất cả những con đường mòn chuột của bạn thực sự đường thẳng? :) Tôi chỉ đang nghĩ đến các cách để di chuyển chuột theo những cách thực tế bằng cách sử dụng mã. Tôi đã googled, tìm kiếm một cơ sở mã nhưng nó là cái gì đó không thực sự được thực hiện. – flavour404

Trả lời

17

Tôi đã thử phương pháp tính toán vòng cung, hóa ra là phức tạp và cuối cùng, nó không có vẻ thực tế. Đường thẳng trông con người hơn nhiều, như JP cho thấy trong bình luận của mình.

Đây là chức năng tôi đã viết để tính toán chuyển động của chuột tuyến tính. Nên khá tự giải thích. GetCursorPosition() và SetCursorPosition (Point) là các trình bao bọc xung quanh các hàm win32 GetCursorPos và SetCursorPos.

Theo như toán học đi - về mặt kỹ thuật, điều này được gọi là Linear Interpolation của một đoạn đường.

public void LinearSmoothMove(Point newPosition, int steps) { 
    Point start = GetCursorPosition(); 
    PointF iterPoint = start; 

    // Find the slope of the line segment defined by start and newPosition 
    PointF slope = new PointF(newPosition.X - start.X, newPosition.Y - start.Y); 

    // Divide by the number of steps 
    slope.X = slope.X/steps; 
    slope.Y = slope.Y/steps; 

    // Move the mouse to each iterative point. 
    for (int i = 0; i < steps; i++) 
    { 
     iterPoint = new PointF(iterPoint.X + slope.X, iterPoint.Y + slope.Y); 
     SetCursorPosition(Point.Round(iterPoint)); 
     Thread.Sleep(MouseEventDelayMS); 
    } 

    // Move the mouse to the final destination. 
    SetCursorPosition(newPosition); 
} 
+2

Tôi biết ai đó sẽ thông minh với toán học! :) –

+0

Vui vì tôi không thất vọng. =) –

+0

Erik, tôi nghĩ tôi đã trả lời tối qua nhưng rõ ràng là tôi mệt mỏi hơn tôi tưởng. Cảm ơn, nó là một câu trả lời tuyệt vời và chắc chắn mang lại cho tôi a) một cái gì đó tôi có thể sử dụng, b) một cái gì đó tôi có thể mở rộng trên. Câu trả lời chính xác. Tôi sẽ nhớ những gì bạn nói về vòng cung. – flavour404

1

Một cách thông thường, tôi nghĩ, là thể chất di chuyển con chuột thực sự với tay của riêng bạn: và có phần mềm chụp lại những người (thực tế) phong trào, và phát lại chúng.

3
procedure WindMouse(xs, ys, xe, ye, gravity, wind, minWait, maxWait, maxStep, targetArea: extended); 
var 
    veloX, veloY, windX, windY, veloMag, dist, randomDist, lastDist, step: extended; 
    lastX, lastY: integer; 
    sqrt2, sqrt3, sqrt5: extended; 
begin 
    sqrt2:= sqrt(2); 
    sqrt3:= sqrt(3); 
    sqrt5:= sqrt(5); 
    while hypot(xs - xe, ys - ye) > 1 do 
    begin 
    dist:= hypot(xs - xe, ys - ye); 
    wind:= minE(wind, dist); 
    if dist >= targetArea then 
    begin 
     windX:= windX/sqrt3 + (random(round(wind) * 2 + 1) - wind)/sqrt5; 
     windY:= windY/sqrt3 + (random(round(wind) * 2 + 1) - wind)/sqrt5; 
    end else 
    begin 
     windX:= windX/sqrt2; 
     windY:= windY/sqrt2; 
     if (maxStep < 3) then 
     begin 
     maxStep:= random(3) + 3.0; 
     end else 
     begin 
     maxStep:= maxStep/sqrt5; 
     end; 
    end; 
    veloX:= veloX + windX; 
    veloY:= veloY + windY; 
    veloX:= veloX + gravity * (xe - xs)/dist; 
    veloY:= veloY + gravity * (ye - ys)/dist; 
    if hypot(veloX, veloY) > maxStep then 
    begin 
     randomDist:= maxStep/2.0 + random(round(maxStep)/2); 
     veloMag:= sqrt(veloX * veloX + veloY * veloY); 
     veloX:= (veloX/veloMag) * randomDist; 
     veloY:= (veloY/veloMag) * randomDist; 
    end; 
    lastX:= Round(xs); 
    lastY:= Round(ys); 
    xs:= xs + veloX; 
    ys:= ys + veloY; 
    if (lastX <> Round(xs)) or (lastY <> Round(ys)) then 
     MoveMouse(Round(xs), Round(ys)); 
    step:= hypot(xs - lastX, ys - lastY); 
    wait(round((maxWait - minWait) * (step/maxStep) + minWait)); 
    lastdist:= dist; 
    end; 
    if (Round(xe) <> Round(xs)) or (Round(ye) <> Round(ys)) then 
    MoveMouse(Round(xe), Round(ye)); 
end; 

{******************************************************************************* 
procedure MMouse(x, y, rx, ry: integer); 
By: Benland100 
Description: Moves the mouse. 
*******************************************************************************} 
//Randomness is just added to the x,y. Might want to change that. 
procedure MMouse(x, y, rx, ry: integer); 
var 
    cx, cy: integer; 
    randSpeed: extended; 
begin 
    randSpeed:= (random(MouseSpeed)/2.0 + MouseSpeed)/10.0; 
    if randSpeed = 0.0 then 
    randSpeed := 0.1; 
    getMousePos(cx,cy); 
    X := x + random(rx); 
    Y := y + random(ry); 
    WindMouse(cx,cy,x,y,9.0,3.0,10.0/randSpeed,15.0/randSpeed,10.0*randSpeed,10.0*randSpeed); 
end; 

Dưới đây là một số phương pháp viết bằng SCAR. Chuyển đổi chúng C# không nên quá khó, đây là khá thực tế.

+0

Cảm ơn một người nào đó, tôi sẽ xem xét. Thú vị biệt danh! :) – flavour404

+0

Tôi đã cố gắng để làm việc ra những gì các minE() chức năng nào, bất kỳ ý tưởng? – flavour404

+0

@ flavour404 - 'minE()' Trả lại giá trị nhỏ hơn của hai biến - 'Math.Min()' hoặc tương tự. Nguồn: http://forums.freddy1990.com/index.php?topic=4214.0 –

8

Tôi đã chuyển đổi hàm WindMouse được đề cập trước đó vào C# và thực tế là khá thực tế. Lưu ý rằng đây chỉ là mẫu thô và không sử dụng trình bao bọc cho GetCursorPosSetCursorPos. Tôi sẽ sử dụng trình bao bọc Windows Input Simulator.

static class SampleMouseMove { 

    static Random random = new Random(); 
    static int mouseSpeed = 15; 

    static void Main(string[] args) { 
     MoveMouse(0, 0, 0, 0); 
    } 

    static void MoveMouse(int x, int y, int rx, int ry) { 
     Point c = new Point(); 
     GetCursorPos(out c); 

     x += random.Next(rx); 
     y += random.Next(ry); 

     double randomSpeed = Math.Max((random.Next(mouseSpeed)/2.0 + mouseSpeed)/10.0, 0.1); 

     WindMouse(c.X, c.Y, x, y, 9.0, 3.0, 10.0/randomSpeed, 
      15.0/randomSpeed, 10.0 * randomSpeed, 10.0 * randomSpeed); 
    } 

    static void WindMouse(double xs, double ys, double xe, double ye, 
     double gravity, double wind, double minWait, double maxWait, 
     double maxStep, double targetArea) { 

     double dist, windX = 0, windY = 0, veloX = 0, veloY = 0, randomDist, veloMag, step; 
     int oldX, oldY, newX = (int)Math.Round(xs), newY = (int)Math.Round(ys); 

     double waitDiff = maxWait - minWait; 
     double sqrt2 = Math.Sqrt(2.0); 
     double sqrt3 = Math.Sqrt(3.0); 
     double sqrt5 = Math.Sqrt(5.0); 

     dist = Hypot(xe - xs, ye - ys); 

     while (dist > 1.0) { 

      wind = Math.Min(wind, dist); 

      if (dist >= targetArea) { 
       int w = random.Next((int)Math.Round(wind) * 2 + 1); 
       windX = windX/sqrt3 + (w - wind)/sqrt5; 
       windY = windY/sqrt3 + (w - wind)/sqrt5; 
      } 
      else { 
       windX = windX/sqrt2; 
       windY = windY/sqrt2; 
       if (maxStep < 3) 
        maxStep = random.Next(3) + 3.0; 
       else 
        maxStep = maxStep/sqrt5; 
      } 

      veloX += windX; 
      veloY += windY; 
      veloX = veloX + gravity * (xe - xs)/dist; 
      veloY = veloY + gravity * (ye - ys)/dist; 

      if (Hypot(veloX, veloY) > maxStep) { 
       randomDist = maxStep/2.0 + random.Next((int)Math.Round(maxStep)/2); 
       veloMag = Hypot(veloX, veloY); 
       veloX = (veloX/veloMag) * randomDist; 
       veloY = (veloY/veloMag) * randomDist; 
      } 

      oldX = (int)Math.Round(xs); 
      oldY = (int)Math.Round(ys); 
      xs += veloX; 
      ys += veloY; 
      dist = Hypot(xe - xs, ye - ys); 
      newX = (int)Math.Round(xs); 
      newY = (int)Math.Round(ys); 

      if (oldX != newX || oldY != newY) 
       SetCursorPos(newX, newY); 

      step = Hypot(xs - oldX, ys - oldY); 
      int wait = (int)Math.Round(waitDiff * (step/maxStep) + minWait); 
      Thread.Sleep(wait); 
     } 

     int endX = (int)Math.Round(xe); 
     int endY = (int)Math.Round(ye); 
     if (endX != newX || endY != newY) 
      SetCursorPos(endX, endY); 
    } 

    static double Hypot(double dx, double dy) { 
     return Math.Sqrt(dx * dx + dy * dy); 
    } 

    [DllImport("user32.dll")] 
    static extern bool SetCursorPos(int X, int Y); 

    [DllImport("user32.dll")] 
    public static extern bool GetCursorPos(out Point p); 
} 
Các vấn đề liên quan