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 }