github.com/sandwich-go/boost@v1.3.29/geom/int64.go (about)

     1  // Code generated by tools. DO NOT EDIT.
     2  package geom
     3  
     4  import "strconv"
     5  
     6  // PointInt64 point wrapper
     7  type PointInt64 struct {
     8  	X, Y int64
     9  }
    10  
    11  // String returns a string representation of p like "(3,4)".
    12  func (p PointInt64) String() string {
    13  	return "(" + strconv.FormatInt(int64(p.X), 10) + "," + strconv.FormatInt(int64(p.Y), 10) + ")"
    14  }
    15  
    16  // Add returns the vector p+q.
    17  func (p PointInt64) Add(q PointInt64) PointInt64 {
    18  	return PointInt64{p.X + q.X, p.Y + q.Y}
    19  }
    20  
    21  // Sub returns the vector p-q.
    22  func (p PointInt64) Sub(q PointInt64) PointInt64 {
    23  	return PointInt64{p.X - q.X, p.Y - q.Y}
    24  }
    25  
    26  // Mul returns the vector p*k.
    27  func (p PointInt64) Mul(k int64) PointInt64 {
    28  	return PointInt64{p.X * k, p.Y * k}
    29  }
    30  
    31  // Div returns the vector p/k.
    32  func (p PointInt64) Div(k int64) PointInt64 {
    33  	return PointInt64{p.X / k, p.Y / k}
    34  }
    35  
    36  // In reports whether p is in r.
    37  func (p PointInt64) In(r RectangleInt64) bool {
    38  	return r.Min.X <= p.X && p.X <= r.Max.X && r.Min.Y <= p.Y && p.Y <= r.Max.Y
    39  }
    40  
    41  // Eq reports whether p and q are equal.
    42  func (p PointInt64) Eq(q PointInt64) bool {
    43  	return p == q
    44  }
    45  
    46  // ZPInt64 is the zero PointInt64.
    47  var ZPInt64 PointInt64
    48  
    49  // PtInt64 is shorthand for PointInt64.{X, Y}.
    50  func PtInt64(X, Y int64) PointInt64 {
    51  	return PointInt64{X, Y}
    52  }
    53  
    54  // RectangleInt64 rectangle wrapper, contain two point.
    55  type RectangleInt64 struct {
    56  	Min, Max PointInt64
    57  }
    58  
    59  // String returns a string representation of r like "(3,4)-(6,5)".
    60  func (r RectangleInt64) String() string {
    61  	return r.Min.String() + "-" + r.Max.String()
    62  }
    63  
    64  // RangePoints range all points in rectangle.
    65  // if with return false, aborted range.
    66  func (r RectangleInt64) RangePoints(with func(p PointInt64) bool) {
    67  	if with == nil || r == ZRInt64 {
    68  		return
    69  	}
    70  	for x := r.Min.X; x <= r.Max.X; x++ {
    71  		for y := r.Min.Y; y <= r.Max.Y; y++ {
    72  			if !with(PtInt64(x, y)) {
    73  				return
    74  			}
    75  		}
    76  	}
    77  }
    78  
    79  // RangePointsMinClosedMaxOpen range all points in rectangle except min x, y.
    80  // if with return false, aborted range.
    81  func (r RectangleInt64) RangePointsMinClosedMaxOpen(with func(p PointInt64) bool) {
    82  	if with == nil || r == ZRInt64 {
    83  		return
    84  	}
    85  	for x := r.Min.X + 1; x <= r.Max.X; x++ {
    86  		for y := r.Min.Y + 1; y <= r.Max.Y; y++ {
    87  			if !with(PtInt64(x, y)) {
    88  				return
    89  			}
    90  		}
    91  	}
    92  }
    93  
    94  // IntersectionWithLine check line intersection, if intersection, return true
    95  func (r RectangleInt64) IntersectionWithLine(s PointInt64, e PointInt64) bool {
    96  	if s.X <= r.Min.X && e.X <= r.Min.X || s.X >= r.Max.X && e.X >= r.Max.X || s.Y <= r.Min.Y && e.Y <= r.Min.Y || s.Y >= r.Max.Y && e.Y >= r.Max.Y {
    97  		return false
    98  	}
    99  	a := s.Y - e.Y
   100  	b := e.X - s.X
   101  	c := e.Y*s.X - e.X*s.Y
   102  	if ((a*r.Min.X+b*r.Min.Y+c)*(a*r.Max.X+b*r.Max.Y+c)) <= 0 || ((a*r.Max.X+b*r.Min.Y+c)*(a*r.Min.X+b*r.Max.Y+c)) <= 0 {
   103  		return true
   104  	}
   105  	return false
   106  }
   107  
   108  // RangePointsMinMaxClosed range all points in rectangle except min/max x, y.
   109  // if with return false, aborted range.
   110  func (r RectangleInt64) RangePointsMinMaxClosed(with func(p PointInt64) bool) {
   111  	if with == nil || r == ZRInt64 {
   112  		return
   113  	}
   114  	for x := r.Min.X + 1; x < r.Max.X; x++ {
   115  		for y := r.Min.Y + 1; y < r.Max.Y; y++ {
   116  			if !with(PtInt64(x, y)) {
   117  				return
   118  			}
   119  		}
   120  	}
   121  }
   122  
   123  // RangePointsMinOpenMaxClosed range all points in rectangle except max x, y.
   124  // if with return false, aborted range.
   125  func (r RectangleInt64) RangePointsMinOpenMaxClosed(with func(p PointInt64) bool) {
   126  	if with == nil || r == ZRInt64 {
   127  		return
   128  	}
   129  	for x := r.Min.X; x < r.Max.X; x++ {
   130  		for y := r.Min.Y; y < r.Max.Y; y++ {
   131  			if !with(PtInt64(x, y)) {
   132  				return
   133  			}
   134  		}
   135  	}
   136  }
   137  
   138  // Dx returns r's width.
   139  func (r RectangleInt64) Dx() int64 {
   140  	return r.Max.X - r.Min.X
   141  }
   142  
   143  // Dy returns r's height.
   144  func (r RectangleInt64) Dy() int64 {
   145  	return r.Max.Y - r.Min.Y
   146  }
   147  
   148  // Size returns r's width and height.
   149  func (r RectangleInt64) Size() PointInt64 {
   150  	return PointInt64{
   151  		r.Max.X - r.Min.X,
   152  		r.Max.Y - r.Min.Y,
   153  	}
   154  }
   155  
   156  // Add returns the rectangle r translated by p.
   157  func (r RectangleInt64) Add(p PointInt64) RectangleInt64 {
   158  	return RectangleInt64{
   159  		PointInt64{r.Min.X + p.X, r.Min.Y + p.Y},
   160  		PointInt64{r.Max.X + p.X, r.Max.Y + p.Y},
   161  	}
   162  }
   163  
   164  // Sub returns the rectangle r translated by -p.
   165  func (r RectangleInt64) Sub(p PointInt64) RectangleInt64 {
   166  	return RectangleInt64{
   167  		PointInt64{r.Min.X - p.X, r.Min.Y - p.Y},
   168  		PointInt64{r.Max.X - p.X, r.Max.Y - p.Y},
   169  	}
   170  }
   171  
   172  // Inset returns the rectangle r inset by n, which may be negative. If either
   173  // of r's dimensions is less than 2*n then an empty rectangle near the center
   174  // of r will be returned.
   175  func (r RectangleInt64) Inset(n int64) RectangleInt64 {
   176  	if r.Dx() < 2*n {
   177  		r.Min.X = (r.Min.X + r.Max.X) / 2
   178  		r.Max.X = r.Min.X
   179  	} else {
   180  		r.Min.X += n
   181  		r.Max.X -= n
   182  	}
   183  	if r.Dy() < 2*n {
   184  		r.Min.Y = (r.Min.Y + r.Max.Y) / 2
   185  		r.Max.Y = r.Min.Y
   186  	} else {
   187  		r.Min.Y += n
   188  		r.Max.Y -= n
   189  	}
   190  	return r
   191  }
   192  
   193  // Intersect returns the largest rectangle contained by both r and s. If the
   194  // two rectangles do not overlap then the zero rectangle will be returned.
   195  func (r RectangleInt64) Intersect(s RectangleInt64) RectangleInt64 {
   196  	if r.Min.X < s.Min.X {
   197  		r.Min.X = s.Min.X
   198  	}
   199  	if r.Min.Y < s.Min.Y {
   200  		r.Min.Y = s.Min.Y
   201  	}
   202  	if r.Max.X > s.Max.X {
   203  		r.Max.X = s.Max.X
   204  	}
   205  	if r.Max.Y > s.Max.Y {
   206  		r.Max.Y = s.Max.Y
   207  	}
   208  	// Letting r0 and s0 be the values of r and s at the time that the method
   209  	// is called, this next line is equivalent to:
   210  	//
   211  	// if max(r0.Min.X, s0.Min.X) >= min(r0.Max.X, s0.Max.X) || likewiseForY { etc }
   212  	if r.Empty() {
   213  		return ZRInt64
   214  	}
   215  	return r
   216  }
   217  
   218  // Union returns the smallest rectangle that contains both r and s.
   219  func (r RectangleInt64) Union(s RectangleInt64) RectangleInt64 {
   220  	if r.Empty() {
   221  		return s
   222  	}
   223  	if s.Empty() {
   224  		return r
   225  	}
   226  	if r.Min.X > s.Min.X {
   227  		r.Min.X = s.Min.X
   228  	}
   229  	if r.Min.Y > s.Min.Y {
   230  		r.Min.Y = s.Min.Y
   231  	}
   232  	if r.Max.X < s.Max.X {
   233  		r.Max.X = s.Max.X
   234  	}
   235  	if r.Max.Y < s.Max.Y {
   236  		r.Max.Y = s.Max.Y
   237  	}
   238  	return r
   239  }
   240  
   241  // Empty reports whether the rectangle contains no points.
   242  func (r RectangleInt64) Empty() bool {
   243  	return r.Min.X >= r.Max.X || r.Min.Y >= r.Max.Y
   244  }
   245  
   246  // Eq reports whether r and s contain the same set of points. All empty
   247  // rectangles are considered equal.
   248  func (r RectangleInt64) Eq(s RectangleInt64) bool {
   249  	return r == s || r.Empty() && s.Empty()
   250  }
   251  
   252  // Overlaps reports whether r and s have a non-empty intersection.
   253  func (r RectangleInt64) Overlaps(s RectangleInt64) bool {
   254  	return !r.Empty() && !s.Empty() &&
   255  		r.Min.X < s.Max.X && s.Min.X < r.Max.X &&
   256  		r.Min.Y < s.Max.Y && s.Min.Y < r.Max.Y
   257  }
   258  
   259  // In reports whether every point in r is in s.
   260  func (r RectangleInt64) In(s RectangleInt64) bool {
   261  	if r.Empty() {
   262  		return true
   263  	}
   264  	// Note that r.Max is an exclusive bound for r, so that r.In(s)
   265  	// does not require that r.Max.In(s).
   266  	return s.Min.X <= r.Min.X && r.Max.X <= s.Max.X &&
   267  		s.Min.Y <= r.Min.Y && r.Max.Y <= s.Max.Y
   268  }
   269  
   270  // Bounds returns a rectangle bounds
   271  func (r RectangleInt64) Bounds() RectangleInt64 {
   272  	return r
   273  }
   274  
   275  // Expanded returns a rectangle that has been expanded in the x-direction
   276  // by margin.X, and in y-direction by margin.Y. The resulting rectangle may be empty.
   277  func (r RectangleInt64) Expanded(margin PointInt64) RectangleInt64 {
   278  	return RectangleInt64{
   279  		PointInt64{r.Min.X - margin.X, r.Min.Y - margin.Y},
   280  		PointInt64{r.Max.X + margin.X, r.Max.Y + margin.Y},
   281  	}
   282  }
   283  
   284  // ExpandedByMargin returns a rectangle that has been expanded in the x-direction
   285  // by margin, and in y-direction by margin. The resulting rectangle may be empty.
   286  func (r RectangleInt64) ExpandedByMargin(margin int64) RectangleInt64 {
   287  	return r.Expanded(PtInt64(margin, margin))
   288  }
   289  
   290  // ZRInt64 is the zero RectangleInt64.
   291  var ZRInt64 RectangleInt64
   292  
   293  // RectInt64 is shorthand for RectangleInt64{Pt(x0, y0), Pt(x1, y1)}. The returned
   294  // rectangle has minimum and maximum coordinates swapped if necessary so that
   295  // it is well-formed.
   296  func RectInt64(x0, y0, x1, y1 int64) RectangleInt64 {
   297  	if x0 > x1 {
   298  		x0, x1 = x1, x0
   299  	}
   300  	if y0 > y1 {
   301  		y0, y1 = y1, y0
   302  	}
   303  	return RectangleInt64{PointInt64{x0, y0}, PointInt64{x1, y1}}
   304  }
   305  
   306  // RectInt64FromCenterSize constructs a rectangle with the given center and size.
   307  // Both dimensions of size must be non-negative.
   308  func RectInt64FromCenterSize(center, size PointInt64) RectangleInt64 {
   309  	return RectInt64(center.X-size.X, center.Y-center.Y, center.X+size.X, center.Y+size.Y)
   310  }
   311  
   312  // HelixRectRangeFromCenterAndMarginInt64 由center节点逆时针螺旋由内向外访问margin区域内的所有节点
   313  // 25   24   23   22   21
   314  // 10    9    8    7   20
   315  // 11    2    1    6   19
   316  // 12    3    4    5   18
   317  // 13   14   15   16   17
   318  func HelixRectRangeFromCenterAndMarginInt64(center PointInt64, margin int64, with func(p PointInt64) bool) {
   319  	var x, y, xNow, yNow int64
   320  	xLen, yLen := int64(1), int64(1)
   321  	rectXYLen := margin*2 + 1
   322  	m, max := int64(0), rectXYLen*rectXYLen
   323  	startX, startY := center.X, center.Y
   324  
   325  	for m <= max {
   326  		for x = startX; x >= startX-xLen; x-- {
   327  			m++
   328  			if m > max || !with(PtInt64(x, startY)) {
   329  				return
   330  			}
   331  		}
   332  		for y = startY - 1; y >= startY-yLen; y-- {
   333  			m++
   334  			if m > max || !with(PtInt64(x+1, y)) {
   335  				return
   336  			}
   337  		}
   338  		xLen++
   339  		yLen++
   340  		for xNow = x + 2; xNow <= x+xLen; xNow++ {
   341  			m++
   342  			if m > max || !with(PtInt64(xNow, y+1)) {
   343  				return
   344  			}
   345  		}
   346  		for yNow = y + 1; yNow <= y+yLen; yNow++ {
   347  			m++
   348  			if m > max || !with(PtInt64(xNow, yNow)) {
   349  				return
   350  			}
   351  		}
   352  		xLen++
   353  		yLen++
   354  		startX = xNow
   355  		startY = yNow
   356  	}
   357  }