in Datasets/COCO/COCO.swift [408:514]
init(fromPolygon xy: [Double], width w: Int, height h: Int) {
// upsample and get discrete points densely along the entire boundary
var k: Int = xy.count / 2
var j: Int = 0
var m: Int = 0
let scale: Double = 5
var x = [Int](repeating: 0, count: k + 1)
var y = [Int](repeating: 0, count: k + 1)
for j in 0..<k { x[j] = Int(scale * xy[j * 2 + 0] + 0.5) }
x[k] = x[0]
for j in 0..<k { y[j] = Int(scale * xy[j * 2 + 1] + 0.5) }
y[k] = y[0]
for j in 0..<k { m += max(abs(x[j] - x[j + 1]), abs(y[j] - y[j + 1])) + 1 }
var u = [Int](repeating: 0, count: m)
var v = [Int](repeating: 0, count: m)
m = 0
for j in 0..<k {
var xs: Int = x[j]
var xe: Int = x[j + 1]
var ys: Int = y[j]
var ye: Int = y[j + 1]
let dx: Int = abs(xe - xs)
let dy: Int = abs(ys - ye)
var t: Int
let flip: Bool = (dx >= dy && xs > xe) || (dx < dy && ys > ye)
if flip {
t = xs
xs = xe
xe = t
t = ys
ys = ye
ye = t
}
let s: Double = dx >= dy ? Double(ye - ys) / Double(dx) : Double(xe - xs) / Double(dy)
if dx >= dy {
for d in 0...dx {
t = flip ? dx - d : d
u[m] = t + xs
let vm = Double(ys) + s * Double(t) + 0.5
v[m] = vm.isNaN ? 0 : Int(vm)
m += 1
}
} else {
for d in 0...dy {
t = flip ? dy - d : d
v[m] = t + ys
let um = Double(xs) + s * Double(t) + 0.5
u[m] = um.isNaN ? 0 : Int(um)
m += 1
}
}
}
// get points along y-boundary and downsample
k = m
m = 0
var xd: Double
var yd: Double
x = [Int](repeating: 0, count: k)
y = [Int](repeating: 0, count: k)
for j in 1..<k {
if u[j] != u[j - 1] {
xd = Double(u[j] < u[j - 1] ? u[j] : u[j] - 1)
xd = (xd + 0.5) / scale - 0.5
if floor(xd) != xd || xd < 0 || xd > Double(w - 1) { continue }
yd = Double(v[j] < v[j - 1] ? v[j] : v[j - 1])
yd = (yd + 0.5) / scale - 0.5
if yd < 0 { yd = 0 } else if yd > Double(h) { yd = Double(h) }
yd = ceil(yd)
x[m] = Int(xd)
y[m] = Int(yd)
m += 1
}
}
// compute rle encoding given y-boundary points
k = m
var a = [UInt32](repeating: 0, count: k + 1)
for j in 0..<k { a[j] = UInt32(x[j] * Int(h) + y[j]) }
a[k] = UInt32(h * w)
k += 1
a.sort()
var p: UInt32 = 0
for j in 0..<k {
let t: UInt32 = a[j]
a[j] -= p
p = t
}
var b = [UInt32](repeating: 0, count: k)
j = 0
m = 0
b[m] = a[j]
m += 1
j += 1
while j < k {
if a[j] > 0 {
b[m] = a[j]
m += 1
j += 1
} else {
j += 1
}
if j < k {
b[m - 1] += a[j]
j += 1
}
}
self.init(width: w, height: h, m: m, counts: b)
}