2013-04-16 34 views
5

phép nói rằng tôi có đầu tiên Point struct của tôi:Làm cách nào để có được tất cả các điểm giữa hai đối tượng Điểm?

Point start = new Point(1, 9); 

và thứ hai của tôi:

Point end = new Point(4, 9); 

Tôi muốn để có được tất cả các điểm giữa điểm bắt đầu và kết thúc. Vì vậy, ví dụ tôi sẽ muốn 2,9 và 3,9 trong một mảng. NET có một cái gì đó được xây dựng trong này?

+9

http://en.wikipedia.org/wiki/Bresenham's_line_algorithm – Patashu

+2

Có * nhiều điểm * vô hạn nằm giữa hai điểm bất kỳ. Bạn có muốn tất cả? –

+0

@CodyGray một 'Điểm' chứa hai giá trị số nguyên. Ít nhất là nó thực hiện trong XNA. Liên kết của Patashu có lẽ là có liên quan. –

Trả lời

5

Không có chức năng xây dựng cho chức năng này vì không có điểm giữa các điểm. Toán học có một dòng giữa hai điểm. Về đồ họa máy tính, các dòng có thể được khử răng cưa và do đó việc làm tròn không được làm tròn thành số nguyên đầy đủ.

Nếu bạn đang tìm kiếm một phương pháp nhanh chóng để tạo tất cả các số tích phân, tôi đoán Bresenhams-Line-Algorithm sẽ là lựa chọn của bạn. Nhưng đây không phải là xây dựng vào NET, bạn phải mã nó bằng chính mình (hoặc có thực hiện Matthew Watson):

http://en.wikipedia.org/wiki/Bresenham's_line_algorithm

Thậm chí có những thuật toán fasther cho làm việc đó, nhưng tôi sẽ đi cho Bresenham.

3

Đây là những gì tôi đã kết thúc. Như @Cody Grey được đề cập trong bình luận của mình, có những điểm vô hạn trên một dòng. Vì vậy, bạn cần phải xác định có bao nhiêu điểm bạn đang tìm kiếm để lấy.

My Dòng lớp:

public class Line { 
    public Point p1, p2; 

    public Line(Point p1, Point p2) { 
     this.p1 = p1; 
     this.p2 = p2; 
    } 

    public Point[] getPoints(int quantity) { 
     var points = new Point[quantity]; 
     int ydiff = p2.Y - p1.Y, xdiff = p2.X - p1.X; 
     double slope = (double)(p2.Y - p1.Y)/(p2.X - p1.X); 
     double x, y; 

     --quantity; 

     for (double i = 0; i < quantity; i++) { 
      y = slope == 0 ? 0 : ydiff * (i/quantity); 
      x = slope == 0 ? xdiff * (i/quantity) : y/slope; 
      points[(int)i] = new Point((int)Math.Round(x) + p1.X, (int)Math.Round(y) + p1.Y); 
     } 

     points[quantity] = p2; 
     return points; 
    } 
} 


Cách sử dụng:

var line = new Line(new Point(10, 15), new Point(297, 316)); 
var points = line.getPoints(20); 

Đó sẽ trả về một mảng điểm 20 điểm cách đều nhau giữa hai thiết bị đầu cuối (bao gồm). Hy vọng rằng sẽ giúp!

+0

của bạn một badass. : O –

+0

nó sẽ làm việc cho đường chéo là tốt? –

+0

@BirajZalavadia Tuyệt đối! –

1

Tôi biết đã khá lâu kể từ khi bạn hỏi câu hỏi này nhưng tôi đã tìm kiếm một cái gì đó tương tự gần đây và tìm thấy wiki này (https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm), có chứa mã giả.

Vì vậy, tôi đã triển khai một hàm có mã giả để thực hiện phép tính này và thêm các điểm vào Danh sách.

public List<Point> GetPoints(Point p1, Point p2) 
{ 
    List<Point> points = new List<Point>(); 

    // no slope (vertical line) 
    if (p1.X == p2.X) 
    { 
     for (double y = p1.Y; y <= p2.Y; y++) 
     { 
      Point p = new Point(p1.X, y); 
      points.Add(p); 
     } 
    } 
    else 
    { 
     // swap p1 and p2 if p2.X < p1.X 
     if (p2.X < p1.X) 
     { 
      Point temp = p1; 
      p1 = p2; 
      p2 = temp; 
     } 

     double deltaX = p2.X - p1.X; 
     double deltaY = p2.Y - p1.Y; 
     double error = -1.0f; 
     double deltaErr = Math.Abs(deltaY/deltaX); 

     double y = p1.Y; 
     for (double x = p1.X; x <= p2.X; x++) 
     { 
      Point p = new Point(x, y); 
      points.Add(p); 
      Debug.WriteLine("Added Point: " + p.X.ToString() + "," + p.Y.ToString()); 

      error += deltaErr; 
      Debug.WriteLine("Error is now: " + error.ToString()); 

      while (error >= 0.0f) 
      { 
       Debug.WriteLine(" Moving Y to " + y.ToString()); 
       y++; 
       points.Add(new Point(x, y)); 
       error -= 1.0f; 
      } 
     } 

     if (points.Last() != p2) 
     { 
      int index = points.IndexOf(p2); 
      points.RemoveRange(index + 1, points.Count - index - 1); 
     } 
    } 

    return points; 
} 
Các vấn đề liên quan