forked from bolom009/go-clipper2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoffset_test.go
More file actions
267 lines (221 loc) · 43.5 KB
/
offset_test.go
File metadata and controls
267 lines (221 loc) · 43.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
package go_clipper2_test
import (
"fmt"
"math"
"reflect"
"testing"
goclipper2 "github.com/epit3d/go-clipper2"
"github.com/stretchr/testify/assert"
)
func TestInflatePaths64(t *testing.T) {
subject := goclipper2.Paths64{
{{0, 0}, {100, 0}, {100, 100}, {0, 100}},
}
tests := []struct {
name string
delta float64
joinType goclipper2.JoinType
endType goclipper2.EndType
overSubject goclipper2.Paths64
expect goclipper2.Paths64
}{
{
name: "offset polygon with squire join type",
delta: 40,
joinType: goclipper2.Square,
endType: goclipper2.Polygon,
expect: goclipper2.Paths64{
{{140, -17}, {140, 117}, {117, 140}, {-17, 140}, {-40, 117}, {-40, -17}, {-17, -40}, {117, -40}},
},
},
}
for i, tt := range tests {
t.Run(fmt.Sprintf("%d:%s", i, tt.name), func(t *testing.T) {
results := goclipper2.InflatePaths64(subject, tt.delta, tt.joinType, tt.endType)
if !reflect.DeepEqual(results, tt.expect) {
t.Errorf("got %v, expect %v", results, tt.expect)
}
})
}
}
func TestInflatePathsD(t *testing.T) {
subject := goclipper2.PathsD{
{{0, 0}, {100, 0}, {100, 100}, {0, 100}},
}
tests := []struct {
name string
delta float64
joinType goclipper2.JoinType
endType goclipper2.EndType
overSubject goclipper2.PathsD
expect goclipper2.PathsD
}{
{
name: "offset polygon with squire join type",
delta: 40,
joinType: goclipper2.Square,
endType: goclipper2.Polygon,
expect: goclipper2.PathsD{
{{140.00, -16.57}, {140.00, 116.57}, {116.57, 140.00}, {-16.57, 140.00}, {-40.00, 116.57}, {-40.00, -16.57}, {-16.57, -40.00}, {116.57, -40.00}},
},
},
{
name: "offset large uncommon polygon",
delta: -3,
joinType: goclipper2.Miter,
endType: goclipper2.Polygon,
overSubject: goclipper2.PathsD{
{{X: 398.09, Y: -288.96}, {X: 375.44, Y: -263.02}, {X: 401.06, Y: -242.65}, {X: 387.56, Y: -208.36}, {X: 429.13, Y: -146.17}, {X: 454.03, Y: -146.17}, {X: 454.03, Y: -111.73}, {X: 486.73, Y: -113.24}, {X: 488.21, Y: -109.07}, {X: 529.19, Y: -125.86}, {X: 529.19, Y: -162.1}, {X: 557.37, Y: -162.1}, {X: 557.37, Y: -126.36}, {X: 584.38, Y: -202.03}, {X: 556.79, Y: -202.03}, {X: 556.79, Y: -236.47}, {X: 641.93, Y: -236.47}, {X: 641.93, Y: -202.03}, {X: 674.63, Y: -203.54}, {X: 701.64, Y: -127.88}, {X: 668.94, Y: -126.36}, {X: 668.94, Y: -88.4}, {X: 529.19, Y: -88.4}, {X: 529.19, Y: -94.81}, {X: 497.89, Y: -81.97}, {X: 513.74, Y: -37.58}, {X: 481.04, Y: -36.06}, {X: 481.04, Y: 1.9}, {X: 341.29, Y: 1.9}, {X: 341.29, Y: -5.98}, {X: 291.13, Y: 1.21}, {X: 297.64, Y: 19.42}, {X: 264.94, Y: 20.94}, {X: 264.94, Y: 58.9}, {X: 125.19, Y: 58.9}, {X: 125.19, Y: 44.37}, {X: 85.44, Y: 44.37}, {X: 90.19, Y: 57.68}, {X: 57.5, Y: 59.19}, {X: 57.5, Y: 97.16}, {X: -82.25, Y: 97.16}, {X: -82.25, Y: 23.45}, {X: -54.07, Y: 23.45}, {X: -54.07, Y: 59.19}, {X: -27.06, Y: -16.48}, {X: -54.65, Y: -16.48}, {X: -54.65, Y: -50.91}, {X: -37.98, Y: -50.91}, {X: -71.39, Y: -102.3}, {X: -161.51, Y: -102.3}, {X: -161.51, Y: -176.0}, {X: -133.33, Y: -176.0}, {X: -133.33, Y: -140.26}, {X: -106.32, Y: -215.93}, {X: -133.91, Y: -215.93}, {X: -133.91, Y: -250.37}, {X: -48.77, Y: -250.37}, {X: -48.77, Y: -215.93}, {X: -16.07, Y: -217.44}, {X: -1.6, Y: -176.93}, {X: 45.59, Y: -165.55}, {X: 45.59, Y: -172.6}, {X: 73.77, Y: -172.6}, {X: 73.77, Y: -136.86}, {X: 100.78, Y: -212.53}, {X: 73.19, Y: -212.53}, {X: 73.19, Y: -246.97}, {X: 107.06, Y: -246.97}, {X: 107.06, Y: -280.42}, {X: 95.65, Y: -280.82}, {X: 79.22, Y: -311.72}, {X: 97.77, Y: -341.4}, {X: 132.75, Y: -340.18}, {X: 144.21, Y: -318.61}, {X: 242.42, Y: -282.09}, {X: 264.25, Y: -307.09}, {X: 285.48, Y: -288.56}, {X: 261.97, Y: -261.64}, {X: 332.08, Y: -300.87}, {X: 311.3, Y: -319.02}, {X: 333.95, Y: -344.96}},
},
expect: goclipper2.PathsD{
{{393.85, -288.67}, {371.11, -262.63}, {397.45, -241.67}, {384.19, -208}, {427.53, -143.17}, {451.03, -143.17}, {451.03, -108.59}, {484.64, -110.13}, {486.44, -105.1}, {532.19, -123.85}, {532.19, -159.1}, {554.37, -159.1}, {554.37, -123.83}, {559.35, -122.97}, {588.64, -205.03}, {559.79, -205.03}, {559.79, -233.47}, {638.93, -233.47}, {638.93, -198.89}, {672.54, -200.43}, {697.44, -130.69}, {665.94, -129.22}, {665.94, -91.4}, {532.19, -91.4}, {532.19, -99.28}, {494.1, -83.66}, {509.54, -40.39}, {478.04, -38.92}, {478.04, -1.1}, {344.29, -1.1}, {344.29, -9.44}, {287.07, -1.24}, {293.45, 16.61}, {261.94, 18.08}, {261.94, 55.9}, {128.19, 55.9}, {128.19, 41.37}, {81.18, 41.37}, {85.99, 54.87}, {54.5, 56.33}, {54.5, 94.16}, {-79.25, 94.16}, {-79.25, 26.45}, {-57.07, 26.45}, {-57.07, 61.72}, {-52.09, 62.58}, {-22.8, -19.48}, {-51.65, -19.48}, {-51.65, -47.91}, {-36.19, -47.91}, {-34.49, -51.05}, {-69.76, -105.3}, {-158.51, -105.3}, {-158.51, -173}, {-136.33, -173}, {-136.33, -137.73}, {-131.35, -136.87}, {-102.06, -218.93}, {-130.91, -218.93}, {-130.91, -247.37}, {-51.77, -247.37}, {-51.77, -212.79}, {-18.16, -214.33}, {-3.88, -174.39}, {48.59, -161.74}, {48.59, -169.6}, {70.77, -169.6}, {70.77, -134.33}, {75.75, -133.47}, {105.04, -215.53}, {76.19, -215.53}, {76.19, -243.97}, {110.06, -243.97}, {110.06, -283.32}, {97.49, -283.75}, {82.68, -311.6}, {99.39, -338.33}, {130.92, -337.24}, {142.1, -316.2}, {243.32, -278.56}, {264.53, -302.86}, {281.24, -288.27}, {258.05, -261.71}, {261.23, -257.79}, {337.26, -300.33}, {315.53, -319.3}, {334.23, -340.72}},
},
},
}
for i, tt := range tests {
t.Run(fmt.Sprintf("%d:%s", i, tt.name), func(t *testing.T) {
if tt.overSubject != nil {
subject = tt.overSubject
}
results := goclipper2.InflatePathsD(subject, tt.delta, tt.joinType, tt.endType)
if !reflect.DeepEqual(results, tt.expect) {
t.Errorf("got %v, \n\t\t expect %v", results, tt.expect)
}
})
}
}
func TestChainInflatePathsD(t *testing.T) {
circle := circlePath(5.0, 5.0, 3.0, 32)
circle2 := circlePath(7.0, 7.0, 1.0, 32)
rectangle := goclipper2.MakePathD(0.0, 0.0, 5.0, 0.0, 5.0, 6.0, 0.0, 6.0)
result1 := goclipper2.DifferenceWithClipPathsD(goclipper2.PathsD{circle}, goclipper2.PathsD{circle2, rectangle}, goclipper2.EvenOdd)
result2 := goclipper2.InflatePathsD(result1, 1.0, goclipper2.Round, goclipper2.Polygon, goclipper2.WithMitterLimit(0.0))
assert.Equal(t, 1, len(result2))
assert.Equal(t, 117, len(result2[0]))
}
func circlePath(offsetX, offsetY, radius float64, segments int) goclipper2.PathD {
pts := make(goclipper2.PathD, 0, segments)
for i := 0; i < segments; i++ {
angle := float64(i) / float64(segments) * 2.0 * math.Pi
x := math.Sin(angle)*radius + offsetX
y := math.Cos(angle)*radius + offsetY
pts = append(pts, goclipper2.PointD{X: x, Y: y})
}
return pts
}
func TestOffsetCallback(t *testing.T) {
const scale = 10
const delta = 10.0 * scale
ellipse := goclipper2.PathDToPath64(circlePath(0, 0, scale*180, 100))
solution := goclipper2.Paths64{}
co := goclipper2.NewClipperOffset(0.0, 10.0, true, false)
co.AddPaths(goclipper2.Paths64{ellipse}, goclipper2.Miter, goclipper2.RoundET)
var deltaFunc goclipper2.DeltaCallbackFunc = func(path *goclipper2.Path64, path_normals *goclipper2.PathD, curr_idx, prev_idx int) float64 {
// gradually scale down the offset to a minimum of 25% of delta
midIndex := (len(*path) / 2)
factor := 1.0 - (float64(curr_idx) / float64(midIndex) * 0.75)
return delta * factor
}
co.SetDeltaCallback(&deltaFunc)
co.Execute64(10.0, &solution)
var expected = goclipper2.Paths64{{{115, -1822}, {228, -1813}, {342, -1797}, {455, -1773}, {566, -1742}, {675, -1705}, {781, -1660}, {885, -1609}, {985, -1552}, {1082, -1488}, {1173, -1418}, {1261, -1343}, {1345, -1262}, {1421, -1176}, {1494, -1086}, {1560, -990}, {1621, -891}, {1675, -788}, {1723, -682}, {1763, -573}, {1798, -461}, {1825, -348}, {1844, -232}, {1857, -117}, {1863, 0}, {1860, 117}, {1850, 233}, {1834, 349}, {1809, 464}, {1778, 578}, {1740, 688}, {1694, 797}, {1642, 903}, {1583, 1005}, {1519, 1104}, {1447, 1197}, {1371, 1287}, {1288, 1372}, {1200, 1450}, {1108, 1525}, {1010, 1592}, {909, 1654}, {804, 1709}, {695, 1758}, {585, 1799}, {471, 1834}, {355, 1862}, {237, 1881}, {120, 1894}, {0, 1800}, {103, 1704}, {103, 1698}, {216, 1688}, {216, 1689}, {316, 1675}, {426, 1651}, {426, 1652}, {530, 1622}, {530, 1623}, {631, 1587}, {730, 1546}, {827, 1498}, {916, 1448}, {916, 1447}, {1009, 1386}, {1095, 1320}, {1095, 1321}, {1178, 1250}, {1255, 1175}, {1326, 1095}, {1395, 1010}, {1456, 922}, {1510, 834}, {1510, 833}, {1563, 733}, {1607, 634}, {1645, 532}, {1677, 428}, {1703, 322}, {1720, 215}, {1732, 107}, {1738, 2}, {1735, -107}, {1726, -216}, {1711, -324}, {1688, -434}, {1659, -537}, {1624, -641}, {1580, -745}, {1532, -844}, {1478, -937}, {1419, -1029}, {1351, -1117}, {1278, -1203}, {1204, -1280}, {1121, -1353}, {1033, -1425}, {944, -1486}, {848, -1545}, {752, -1595}, {648, -1642}, {545, -1680}, {438, -1713}, {330, -1739}, {221, -1757}, {110, -1770}, {-1, -1774}, {-112, -1773}, {-111, -1773}, {-223, -1763}, {-222, -1763}, {-333, -1748}, {-332, -1748}, {-443, -1724}, {-444, -1724}, {-551, -1694}, {-552, -1694}, {-657, -1658}, {-656, -1658}, {-760, -1615}, {-759, -1615}, {-861, -1565}, {-862, -1565}, {-958, -1509}, {-1052, -1448}, {-1142, -1379}, {-1227, -1307}, {-1308, -1228}, {-1383, -1144}, {-1384, -1144}, {-1454, -1056}, {-1455, -1056}, {-1518, -963}, {-1577, -867}, {-1520, -965}, {-1458, -1059}, {-1389, -1150}, {-1316, -1236}, {-1237, -1317}, {-1152, -1393}, {-1064, -1464}, {-970, -1529}, {-873, -1588}, {-772, -1641}, {-668, -1688}, {-561, -1728}, {-452, -1761}, {-341, -1788}, {-228, -1807}, {-115, -1819}, {0, -1825}}}
assert.Equal(t, expected, solution)
}
// Test1 - Variable offset callback that gradually scales down
func TestOffsetVariableCallback1(t *testing.T) {
const scale = 10
delta := 10.0 * scale
co := goclipper2.NewClipperOffset(0.0, 10.0, true, false)
// Create ellipse
subject := goclipper2.Paths64{goclipper2.Ellipse64(goclipper2.Point64{X: 0, Y: 0}, 200*scale, 180*scale, 256)}
// Resize to 90% as in C++ version
if len(subject[0]) > 0 {
newLen := int(float64(len(subject[0])) * 0.9)
subject[0] = subject[0][:newLen]
}
co.AddPaths(subject, goclipper2.Miter, goclipper2.RoundET)
var deltaFunc goclipper2.DeltaCallbackFunc = func(path *goclipper2.Path64, path_normals *goclipper2.PathD, curr_idx, prev_idx int) float64 {
// gradually scale down the offset to a minimum of 25% of delta
high := float64(len(*path)-1) * 1.25
return (high - float64(curr_idx)) / high * delta
}
co.SetDeltaCallback(&deltaFunc)
solution := goclipper2.Paths64{}
co.Execute64(1.0, &solution)
var expected = goclipper2.Paths64{{{50, -1832}, {99, -1830}, {149, -1827}, {199, -1822}, {248, -1817}, {297, -1812}, {347, -1803}, {395, -1795}, {444, -1785}, {492, -1775}, {540, -1763}, {589, -1750}, {635, -1736}, {683, -1722}, {729, -1705}, {774, -1689}, {820, -1671}, {865, -1651}, {910, -1632}, {954, -1610}, {998, -1589}, {1040, -1566}, {1082, -1543}, {1124, -1518}, {1165, -1492}, {1204, -1466}, {1244, -1438}, {1283, -1410}, {1320, -1381}, {1357, -1351}, {1393, -1321}, {1429, -1289}, {1463, -1257}, {1497, -1224}, {1529, -1190}, {1561, -1156}, {1577, -1107}, {1531, -1128}, {1499, -1162}, {1467, -1194}, {1433, -1225}, {1399, -1257}, {1364, -1287}, {1329, -1316}, {1292, -1345}, {1256, -1372}, {1216, -1400}, {1177, -1426}, {1139, -1451}, {1098, -1476}, {1058, -1499}, {1016, -1522}, {974, -1543}, {932, -1564}, {888, -1584}, {845, -1602}, {800, -1621}, {755, -1637}, {711, -1653}, {666, -1668}, {619, -1682}, {573, -1694}, {525, -1707}, {479, -1717}, {432, -1727}, {384, -1735}, {337, -1743}, {290, -1750}, {242, -1755}, {193, -1760}, {144, -1763}, {96, -1766}, {48, -1766}, {0, -1766}, {-48, -1766}, {-97, -1764}, {-96, -1764}, {-145, -1761}, {-144, -1761}, {-193, -1757}, {-241, -1752}, {-288, -1746}, {-287, -1746}, {-336, -1738}, {-384, -1730}, {-383, -1730}, {-431, -1721}, {-479, -1710}, {-480, -1710}, {-525, -1699}, {-526, -1699}, {-571, -1686}, {-617, -1673}, {-616, -1673}, {-663, -1659}, {-662, -1659}, {-707, -1643}, {-752, -1627}, {-751, -1627}, {-796, -1610}, {-795, -1610}, {-840, -1591}, {-839, -1591}, {-883, -1572}, {-882, -1572}, {-926, -1551}, {-925, -1551}, {-968, -1530}, {-967, -1530}, {-1009, -1508}, {-1008, -1508}, {-1050, -1485}, {-1051, -1485}, {-1090, -1461}, {-1091, -1461}, {-1130, -1436}, {-1168, -1411}, {-1167, -1411}, {-1206, -1384}, {-1244, -1356}, {-1280, -1329}, {-1279, -1329}, {-1316, -1300}, {-1351, -1270}, {-1385, -1240}, {-1418, -1209}, {-1451, -1176}, {-1452, -1176}, {-1482, -1145}, {-1481, -1145}, {-1513, -1112}, {-1512, -1112}, {-1543, -1078}, {-1542, -1078}, {-1570, -1043}, {-1599, -1007}, {-1598, -1007}, {-1626, -972}, {-1625, -972}, {-1652, -935}, {-1675, -899}, {-1700, -861}, {-1699, -861}, {-1723, -823}, {-1724, -823}, {-1744, -785}, {-1765, -746}, {-1784, -707}, {-1803, -669}, {-1802, -669}, {-1820, -628}, {-1836, -587}, {-1852, -548}, {-1851, -548}, {-1866, -507}, {-1865, -507}, {-1879, -466}, {-1878, -466}, {-1890, -423}, {-1900, -381}, {-1911, -338}, {-1919, -297}, {-1925, -256}, {-1932, -212}, {-1936, -170}, {-1941, -126}, {-1944, -87}, {-1943, -87}, {-1944, -43}, {-1945, 1}, {-1943, 43}, {-1942, 84}, {-1939, 126}, {-1934, 170}, {-1928, 214}, {-1921, 255}, {-1914, 296}, {-1905, 339}, {-1894, 380}, {-1883, 421}, {-1872, 462}, {-1858, 503}, {-1844, 544}, {-1843, 543}, {-1827, 583}, {-1810, 625}, {-1811, 626}, {-1792, 665}, {-1773, 702}, {-1754, 740}, {-1732, 779}, {-1711, 816}, {-1688, 853}, {-1662, 890}, {-1637, 928}, {-1638, 929}, {-1613, 961}, {-1585, 996}, {-1557, 1032}, {-1556, 1031}, {-1529, 1064}, {-1499, 1097}, {-1467, 1130}, {-1437, 1161}, {-1403, 1193}, {-1370, 1223}, {-1336, 1253}, {-1300, 1282}, {-1301, 1283}, {-1265, 1309}, {-1229, 1336}, {-1191, 1363}, {-1153, 1389}, {-1117, 1414}, {-1116, 1413}, {-1077, 1438}, {-1076, 1437}, {-1037, 1460}, {-996, 1482}, {-955, 1503}, {-914, 1524}, {-913, 1523}, {-868, 1544}, {-869, 1545}, {-827, 1561}, {-782, 1580}, {-742, 1596}, {-741, 1595}, {-696, 1611}, {-653, 1625}, {-606, 1639}, {-607, 1640}, {-561, 1651}, {-562, 1652}, {-517, 1664}, {-516, 1663}, {-472, 1674}, {-471, 1673}, {-423, 1683}, {-424, 1684}, {-376, 1691}, {-377, 1692}, {-330, 1699}, {-281, 1706}, {-282, 1707}, {-238, 1711}, {-237, 1710}, {-188, 1715}, {-189, 1716}, {-141, 1719}, {-142, 1720}, {-93, 1721}, {-94, 1722}, {-47, 1722}, {-2, 1722}, {47, 1721}, {93, 1721}, {93, 1720}, {142, 1716}, {142, 1717}, {188, 1713}, {188, 1712}, {237, 1707}, {280, 1703}, {280, 1702}, {329, 1694}, {375, 1687}, {375, 1686}, {422, 1678}, {422, 1677}, {468, 1668}, {468, 1667}, {512, 1657}, {512, 1656}, {559, 1644}, {559, 1643}, {604, 1631}, {604, 1630}, {650, 1616}, {692, 1602}, {692, 1601}, {736, 1586}, {736, 1585}, {777, 1569}, {822, 1550}, {863, 1533}, {863, 1532}, {906, 1512}, {906, 1511}, {949, 1490}, {988, 1468}, {988, 1469}, {1029, 1446}, {1068, 1423}, {1107, 1398}, {1143, 1374}, {1180, 1347}, {1216, 1322}, {1216, 1321}, {1253, 1293}, {1287, 1267}, {1287, 1266}, {1322, 1236}, {1353, 1209}, {1353, 1208}, {1387, 1176}, {1421, 1144}, {1449, 1113}, {1449, 1114}, {1480, 1080}, {1509, 1047}, {1536, 1014}, {1564, 979}, {1589, 946}, {1613, 913}, {1613, 912}, {1638, 874}, {1663, 836}, {1685, 799}, {1685, 800}, {1704, 764}, {1726, 724}, {1744, 687}, {1762, 651}, {1779, 610}, {1794, 572}, {1794, 571}, {1810, 530}, {1824, 491}, {1835, 455}, {1835, 454}, {1847, 411}, {1857, 370}, {1868, 327}, {1876, 288}, {1881, 249}, {1887, 209}, {1892, 165}, {1896, 126}, {1896, 125}, {1899, 81}, {1899, 42}, {2000, 0}, {2099, 46}, {2097, 93}, {2094, 141}, {2088, 187}, {2082, 233}, {2075, 279}, {2067, 326}, {2057, 373}, {2045, 418}, {2033, 462}, {2020, 508}, {2005, 554}, {1988, 598}, {1971, 641}, {1953, 685}, {1933, 729}, {1912, 770}, {1913, 770}, {1891, 814}, {1867, 854}, {1868, 854}, {1844, 896}, {1818, 937}, {1792, 976}, {1766, 1015}, {1736, 1055}, {1707, 1093}, {1676, 1130}, {1646, 1166}, {1613, 1203}, {1579, 1238}, {1545, 1273}, {1509, 1306}, {1474, 1339}, {1437, 1371}, {1398, 1403}, {1360, 1433}, {1321, 1461}, {1280, 1490}, {1240, 1518}, {1198, 1545}, {1155, 1571}, {1112, 1596}, {1068, 1619}, {1024, 1642}, {980, 1663}, {934, 1685}, {888, 1704}, {841, 1724}, {794, 1741}, {747, 1757}, {699, 1774}, {650, 1788}, {603, 1801}, {553, 1814}, {504, 1825}, {454, 1835}, {404, 1844}, {355, 1852}, {304, 1860}, {253, 1865}, {203, 1870}, {153, 1873}, {101, 1876}, {51, 1877}, {0, 1878}, {-51, 1876}, {-101, 1875}, {-152, 1871}, {-203, 1867}, {-253, 1861}, {-303, 1856}, {-354, 1847}, {-403, 1839}, {-452, 1829}, {-502, 1818}, {-551, 1807}, {-601, 1793}, {-647, 1779}, {-696, 1764}, {-744, 1747}, {-790, 1731}, {-837, 1713}, {-883, 1693}, {-928, 1673}, {-974, 1651}, {-1018, 1629}, {-1061, 1606}, {-1104, 1582}, {-1147, 1556}, {-1189, 1530}, {-1230, 1503}, {-1269, 1475}, {-1309, 1446}, {-1347, 1416}, {-1385, 1386}, {-1423, 1355}, {-1459, 1322}, {-1493, 1289}, {-1528, 1256}, {-1561, 1221}, {-1594, 1186}, {-1626, 1149}, {-1656, 1113}, {-1685, 1076}, {-1714, 1038}, {-1742, 999}, {-1768, 960}, {-1793, 921}, {-1818, 881}, {-1840, 839}, {-1863, 799}, {-1883, 756}, {-1903, 715}, {-1922, 672}, {-1939, 628}, {-1955, 586}, {-1970, 542}, {-1985, 497}, {-1997, 452}, {-2008, 408}, {-2019, 364}, {-2028, 318}, {-2035, 273}, {-2042, 228}, {-2046, 182}, {-2051, 137}, {-2054, 91}, {-2055, 45}, {-2055, 0}, {-2054, -45}, {-2053, -90}, {-2049, -137}, {-2044, -182}, {-2038, -227}, {-2031, -272}, {-2023, -318}, {-2013, -363}, {-2002, -407}, {-1990, -450}, {-1977, -495}, {-1962, -540}, {-1947, -583}, {-1930, -625}, {-1912, -667}, {-1893, -710}, {-1872, -751}, {-1851, -793}, {-1828, -833}, {-1806, -874}, {-1780, -913}, {-1755, -951}, {-1729, -990}, {-1700, -1028}, {-1672, -1065}, {-1642, -1101}, {-1612, -1137}, {-1580, -1173}, {-1547, -1207}, {-1513, -1241}, {-1478, -1273}, {-1444, -1306}, {-1408, -1337}, {-1370, -1368}, {-1332, -1397}, {-1294, -1425}, {-1254, -1454}, {-1215, -1481}, {-1174, -1507}, {-1132, -1532}, {-1090, -1557}, {-1047, -1580}, {-1004, -1602}, {-960, -1623}, {-915, -1644}, {-870, -1663}, {-824, -1682}, {-778, -1699}, {-733, -1715}, {-686, -1731}, {-637, -1745}, {-591, -1758}, {-542, -1771}, {-494, -1782}, {-445, -1791}, {-396, -1800}, {-348, -1808}, {-298, -1816}, {-249, -1820}, {-199, -1825}, {-149, -1829}, {-99, -1832}, {-50, -1832}, {0, -1833}}}
assert.True(t, reflect.DeepEqual(solution, expected), "solution does not match expected")
}
// Test2 - Variable offset callback based on distance from middle
func TestOffsetVariableCallback2(t *testing.T) {
const scale = 10
delta := 10.0 * scale
co := goclipper2.NewClipperOffset(0.0, 10.0, true, false)
// Create ellipse
subject := goclipper2.Paths64{goclipper2.Ellipse64(goclipper2.Point64{X: 0, Y: 0}, 200*scale, 180*scale, 256)}
// Resize to 90% as in C++ version
if len(subject[0]) > 0 {
newLen := int(float64(len(subject[0])) * 0.9)
subject[0] = subject[0][:newLen]
}
co.AddPaths(subject, goclipper2.Miter, goclipper2.RoundET)
var deltaFunc goclipper2.DeltaCallbackFunc = func(path *goclipper2.Path64, path_normals *goclipper2.PathD, curr_idx, prev_idx int) float64 {
// calculate offset based on distance from the middle of the path
midIdx := float64(len(*path)) / 2.0
absDistance := math.Abs(float64(curr_idx) - midIdx)
return delta * (1.0 - 0.70*(absDistance/midIdx))
}
co.SetDeltaCallback(&deltaFunc)
solution := goclipper2.Paths64{}
co.Execute64(1.0, &solution)
var expected = goclipper2.Paths64{{{50, -1852}, {100, -1850}, {151, -1846}, {201, -1841}, {250, -1836}, {300, -1830}, {350, -1821}, {398, -1813}, {447, -1803}, {496, -1792}, {544, -1780}, {593, -1766}, {640, -1752}, {688, -1737}, {735, -1721}, {780, -1704}, {826, -1686}, {872, -1666}, {916, -1646}, {961, -1624}, {1004, -1602}, {1047, -1579}, {1089, -1555}, {1131, -1530}, {1172, -1504}, {1212, -1477}, {1251, -1449}, {1290, -1420}, {1328, -1391}, {1365, -1361}, {1401, -1330}, {1437, -1298}, {1471, -1265}, {1505, -1232}, {1537, -1198}, {1569, -1163}, {1577, -1107}, {1523, -1121}, {1491, -1154}, {1460, -1185}, {1425, -1217}, {1391, -1248}, {1356, -1278}, {1321, -1307}, {1284, -1335}, {1247, -1362}, {1209, -1389}, {1170, -1415}, {1131, -1440}, {1091, -1464}, {1050, -1487}, {1009, -1509}, {967, -1530}, {925, -1550}, {881, -1570}, {838, -1588}, {795, -1606}, {750, -1622}, {706, -1637}, {661, -1652}, {615, -1665}, {569, -1678}, {521, -1690}, {475, -1700}, {428, -1709}, {382, -1717}, {334, -1725}, {285, -1732}, {240, -1736}, {192, -1740}, {143, -1744}, {95, -1746}, {48, -1746}, {0, -1746}, {-48, -1745}, {-96, -1744}, {-95, -1744}, {-144, -1740}, {-143, -1740}, {-191, -1736}, {-190, -1736}, {-239, -1730}, {-285, -1725}, {-284, -1725}, {-333, -1716}, {-380, -1708}, {-379, -1708}, {-427, -1698}, {-428, -1698}, {-474, -1688}, {-473, -1688}, {-518, -1677}, {-517, -1677}, {-565, -1664}, {-610, -1650}, {-656, -1636}, {-657, -1636}, {-700, -1620}, {-699, -1620}, {-744, -1604}, {-743, -1604}, {-786, -1588}, {-785, -1588}, {-830, -1568}, {-873, -1549}, {-915, -1528}, {-914, -1528}, {-957, -1507}, {-997, -1485}, {-998, -1485}, {-1037, -1463}, {-1036, -1463}, {-1077, -1439}, {-1076, -1439}, {-1115, -1415}, {-1114, -1415}, {-1153, -1389}, {-1152, -1389}, {-1190, -1362}, {-1189, -1362}, {-1228, -1334}, {-1263, -1307}, {-1262, -1307}, {-1298, -1279}, {-1297, -1279}, {-1332, -1250}, {-1331, -1250}, {-1365, -1220}, {-1364, -1220}, {-1398, -1188}, {-1431, -1155}, {-1432, -1155}, {-1461, -1125}, {-1460, -1125}, {-1491, -1092}, {-1490, -1092}, {-1520, -1057}, {-1521, -1057}, {-1547, -1023}, {-1548, -1023}, {-1575, -989}, {-1574, -989}, {-1601, -954}, {-1600, -954}, {-1627, -917}, {-1649, -882}, {-1674, -843}, {-1696, -806}, {-1716, -770}, {-1737, -730}, {-1755, -693}, {-1774, -652}, {-1775, -652}, {-1790, -617}, {-1789, -617}, {-1806, -576}, {-1805, -576}, {-1821, -534}, {-1834, -497}, {-1833, -497}, {-1847, -457}, {-1846, -457}, {-1857, -414}, {-1867, -373}, {-1878, -329}, {-1885, -294}, {-1884, -294}, {-1891, -250}, {-1897, -206}, {-1901, -166}, {-1905, -122}, {-1907, -82}, {-1908, -42}, {-1908, -2}, {-1906, 42}, {-1905, 82}, {-1901, 126}, {-1896, 165}, {-1891, 205}, {-1883, 249}, {-1877, 288}, {-1868, 327}, {-1856, 370}, {-1846, 412}, {-1845, 411}, {-1834, 449}, {-1819, 492}, {-1806, 529}, {-1790, 570}, {-1791, 571}, {-1774, 611}, {-1775, 612}, {-1760, 645}, {-1741, 686}, {-1721, 727}, {-1702, 762}, {-1683, 798}, {-1661, 835}, {-1636, 873}, {-1614, 908}, {-1589, 943}, {-1563, 978}, {-1535, 1013}, {-1509, 1046}, {-1480, 1080}, {-1449, 1113}, {-1421, 1144}, {-1387, 1176}, {-1355, 1207}, {-1321, 1238}, {-1322, 1239}, {-1289, 1265}, {-1254, 1294}, {-1217, 1322}, {-1218, 1323}, {-1181, 1349}, {-1144, 1375}, {-1108, 1400}, {-1069, 1425}, {-1030, 1448}, {-990, 1471}, {-950, 1493}, {-907, 1514}, {-908, 1515}, {-864, 1535}, {-865, 1536}, {-825, 1554}, {-824, 1553}, {-779, 1573}, {-737, 1589}, {-738, 1590}, {-694, 1605}, {-652, 1621}, {-605, 1635}, {-606, 1636}, {-562, 1649}, {-561, 1648}, {-516, 1661}, {-469, 1673}, {-470, 1674}, {-423, 1683}, {-424, 1684}, {-376, 1692}, {-377, 1693}, {-330, 1701}, {-281, 1709}, {-282, 1710}, {-238, 1714}, {-189, 1720}, {-190, 1721}, {-141, 1724}, {-142, 1725}, {-94, 1728}, {-95, 1729}, {-48, 1729}, {1, 1731}, {48, 1731}, {94, 1731}, {94, 1730}, {142, 1729}, {142, 1728}, {189, 1726}, {189, 1725}, {238, 1720}, {286, 1716}, {286, 1717}, {331, 1710}, {331, 1709}, {378, 1703}, {378, 1702}, {425, 1695}, {425, 1694}, {473, 1684}, {473, 1685}, {519, 1674}, {519, 1675}, {565, 1662}, {565, 1663}, {610, 1650}, {657, 1637}, {700, 1622}, {700, 1623}, {745, 1607}, {745, 1608}, {789, 1591}, {789, 1592}, {832, 1574}, {876, 1555}, {918, 1537}, {918, 1536}, {960, 1517}, {960, 1516}, {1001, 1496}, {1001, 1495}, {1044, 1473}, {1084, 1450}, {1084, 1451}, {1124, 1426}, {1161, 1403}, {1161, 1402}, {1199, 1377}, {1199, 1376}, {1239, 1349}, {1275, 1322}, {1312, 1294}, {1347, 1266}, {1381, 1236}, {1415, 1205}, {1447, 1176}, {1447, 1175}, {1479, 1144}, {1479, 1143}, {1512, 1110}, {1542, 1076}, {1570, 1044}, {1570, 1043}, {1599, 1009}, {1599, 1008}, {1628, 973}, {1654, 937}, {1679, 901}, {1704, 863}, {1704, 864}, {1728, 826}, {1728, 827}, {1750, 789}, {1772, 750}, {1792, 711}, {1812, 671}, {1812, 672}, {1830, 632}, {1847, 592}, {1863, 553}, {1863, 552}, {1879, 510}, {1893, 469}, {1905, 427}, {1917, 385}, {1928, 342}, {1937, 301}, {1945, 259}, {1952, 215}, {1958, 172}, {1963, 128}, {1967, 86}, {1968, 43}, {2000, 0}, {2030, 45}, {2029, 89}, {2027, 135}, {2022, 180}, {2018, 224}, {2011, 269}, {2005, 314}, {1996, 359}, {1985, 403}, {1975, 446}, {1963, 491}, {1949, 535}, {1935, 578}, {1919, 620}, {1902, 663}, {1884, 706}, {1864, 747}, {1844, 789}, {1822, 829}, {1800, 870}, {1776, 910}, {1751, 949}, {1726, 988}, {1699, 1027}, {1670, 1064}, {1641, 1101}, {1612, 1137}, {1581, 1174}, {1548, 1209}, {1516, 1243}, {1481, 1277}, {1447, 1310}, {1412, 1342}, {1375, 1373}, {1337, 1404}, {1300, 1433}, {1260, 1462}, {1221, 1490}, {1181, 1517}, {1139, 1544}, {1097, 1569}, {1054, 1593}, {1011, 1616}, {968, 1638}, {923, 1660}, {878, 1680}, {832, 1700}, {785, 1719}, {740, 1735}, {693, 1753}, {644, 1768}, {597, 1781}, {548, 1795}, {500, 1807}, {450, 1818}, {401, 1828}, {353, 1837}, {302, 1846}, {252, 1852}, {202, 1857}, {152, 1862}, {101, 1866}, {50, 1867}, {0, 1869}, {-50, 1869}, {-101, 1868}, {-152, 1866}, {-203, 1862}, {-252, 1858}, {-303, 1853}, {-354, 1845}, {-403, 1838}, {-452, 1829}, {-502, 1819}, {-552, 1808}, {-601, 1795}, {-648, 1783}, {-698, 1769}, {-746, 1753}, {-792, 1737}, {-839, 1720}, {-886, 1700}, {-932, 1681}, {-978, 1660}, {-1023, 1639}, {-1067, 1617}, {-1111, 1593}, {-1154, 1569}, {-1197, 1543}, {-1239, 1516}, {-1279, 1489}, {-1320, 1460}, {-1359, 1432}, {-1398, 1402}, {-1436, 1371}, {-1474, 1338}, {-1509, 1306}, {-1545, 1273}, {-1579, 1238}, {-1613, 1203}, {-1646, 1167}, {-1677, 1130}, {-1708, 1094}, {-1738, 1056}, {-1767, 1017}, {-1794, 977}, {-1820, 939}, {-1846, 898}, {-1870, 856}, {-1894, 815}, {-1916, 772}, {-1937, 731}, {-1957, 686}, {-1975, 643}, {-1993, 600}, {-2008, 555}, {-2023, 509}, {-2035, 462}, {-2046, 418}, {-2056, 373}, {-2066, 325}, {-2073, 279}, {-2079, 233}, {-2084, 187}, {-2089, 141}, {-2091, 92}, {-2092, 46}, {-2092, 0}, {-2090, -46}, {-2089, -92}, {-2085, -140}, {-2079, -186}, {-2073, -232}, {-2065, -278}, {-2057, -324}, {-2047, -371}, {-2035, -415}, {-2023, -459}, {-2010, -505}, {-1994, -550}, {-1978, -594}, {-1961, -637}, {-1942, -680}, {-1923, -724}, {-1901, -766}, {-1880, -808}, {-1856, -849}, {-1833, -890}, {-1807, -930}, {-1781, -968}, {-1754, -1008}, {-1725, -1047}, {-1695, -1084}, {-1665, -1120}, {-1634, -1156}, {-1601, -1193}, {-1568, -1227}, {-1534, -1262}, {-1498, -1294}, {-1463, -1327}, {-1426, -1359}, {-1388, -1390}, {-1349, -1419}, {-1311, -1447}, {-1270, -1476}, {-1230, -1503}, {-1189, -1530}, {-1146, -1555}, {-1103, -1579}, {-1059, -1603}, {-1016, -1625}, {-971, -1646}, {-926, -1667}, {-880, -1686}, {-834, -1705}, {-787, -1722}, {-741, -1738}, {-693, -1754}, {-644, -1768}, {-597, -1780}, {-548, -1793}, {-499, -1804}, {-449, -1813}, {-400, -1822}, {-351, -1830}, {-301, -1837}, {-251, -1842}, {-201, -1846}, {-151, -1850}, {-100, -1852}, {-50, -1853}, {0, -1853}}}
assert.True(t, reflect.DeepEqual(solution, expected), "solution does not match expected")
}
// Test3 - Variable offset using normal vectors
func TestOffsetVariableCallback3(t *testing.T) {
radius := 5000.0
subject := goclipper2.Paths64{goclipper2.Ellipse64(goclipper2.Point64{X: 0, Y: 0}, radius, radius, 200)}
co := goclipper2.NewClipperOffset(0.0, 10.0, true, false)
co.AddPaths(subject, goclipper2.Miter, goclipper2.Polygon)
var deltaFunc goclipper2.DeltaCallbackFunc = func(path *goclipper2.Path64, path_normals *goclipper2.PathD, curr_idx, prev_idx int) float64 {
// when multiplying the x & y of edge unit normal vectors, the value will be
// largest (0.5) when edges are at 45 deg. and least (-0.5) at negative 45 deg.
norm := (*path_normals)[curr_idx]
delta := norm.Y * norm.X
return radius*0.5 + radius*delta
}
co.SetDeltaCallback(&deltaFunc)
solution := goclipper2.Paths64{}
co.Execute64(1.0, &solution)
var expected = goclipper2.Paths64{{{-3054, -8500}, {-2749, -8467}, {-2454, -8434}, {-2161, -8375}, {-1843, -8265}, {-1554, -8199}, {-1296, -8123}, {-1015, -7975}, {-737, -7846}, {-489, -7739}, {-239, -7561}, {0, -7437}, {228, -7243}, {449, -7106}, {652, -6931}, {853, -6721}, {1045, -6572}, {1220, -6418}, {1384, -6199}, {1549, -6020}, {1702, -5856}, {1844, -5676}, {1984, -5513}, {2110, -5332}, {2231, -5155}, {2353, -5000}, {2470, -4849}, {2574, -4682}, {2685, -4540}, {2784, -4387}, {2896, -4262}, {3000, -4129}, {3101, -3998}, {3208, -3878}, {3314, -3759}, {3424, -3646}, {3537, -3537}, {3652, -3430}, {3776, -3329}, {3898, -3224}, {4033, -3128}, {4170, -3029}, {4297, -2920}, {4453, -2826}, {4598, -2719}, {4769, -2622}, {4924, -2508}, {5082, -2392}, {5262, -2278}, {5448, -2156}, {5615, -2020}, {5800, -1884}, {5969, -1735}, {6151, -1583}, {6376, -1424}, {6537, -1242}, {6690, -1064}, {6907, -877}, {7089, -667}, {7232, -457}, {7434, -235}, {7564, 0}, {7751, 245}, {7864, 497}, {8004, 751}, {8161, 1039}, {8241, 1315}, {8319, 1577}, {8443, 1883}, {8505, 2195}, {8547, 2487}, {8591, 2789}, {8603, 3090}, {8619, 3405}, {8611, 3732}, {8571, 4038}, {8521, 4332}, {8466, 4651}, {8370, 4955}, {8273, 5263}, {8141, 5537}, {8016, 5804}, {7859, 6091}, {7682, 6352}, {7495, 6607}, {7289, 6845}, {7071, 7071}, {6839, 7283}, {6592, 7478}, {6335, 7662}, {6063, 7823}, {5775, 7976}, {5514, 8107}, {5221, 8207}, {4920, 8312}, {4603, 8378}, {4294, 8446}, {4000, 8489}, {3685, 8503}, {3359, 8503}, {3054, 8500}, {2749, 8467}, {2454, 8434}, {2161, 8375}, {1843, 8265}, {1554, 8199}, {1296, 8123}, {1015, 7975}, {737, 7846}, {489, 7739}, {239, 7561}, {0, 7437}, {-228, 7243}, {-449, 7106}, {-652, 6931}, {-853, 6721}, {-1045, 6572}, {-1220, 6418}, {-1384, 6199}, {-1549, 6020}, {-1702, 5856}, {-1844, 5676}, {-1984, 5513}, {-2110, 5332}, {-2231, 5155}, {-2353, 5000}, {-2470, 4849}, {-2574, 4682}, {-2685, 4540}, {-2784, 4387}, {-2896, 4262}, {-3000, 4129}, {-3101, 3998}, {-3208, 3878}, {-3314, 3759}, {-3424, 3646}, {-3537, 3537}, {-3652, 3430}, {-3776, 3329}, {-3898, 3224}, {-4033, 3128}, {-4170, 3029}, {-4297, 2920}, {-4453, 2826}, {-4598, 2719}, {-4769, 2622}, {-4924, 2508}, {-5082, 2392}, {-5262, 2278}, {-5448, 2156}, {-5615, 2020}, {-5800, 1884}, {-5969, 1735}, {-6151, 1583}, {-6376, 1424}, {-6537, 1242}, {-6690, 1064}, {-6907, 877}, {-7089, 667}, {-7232, 457}, {-7434, 235}, {-7564, 0}, {-7751, -245}, {-7864, -497}, {-8004, -751}, {-8161, -1039}, {-8241, -1315}, {-8319, -1577}, {-8443, -1883}, {-8505, -2195}, {-8547, -2487}, {-8591, -2789}, {-8603, -3090}, {-8619, -3405}, {-8611, -3732}, {-8571, -4038}, {-8521, -4332}, {-8466, -4651}, {-8370, -4955}, {-8273, -5263}, {-8141, -5537}, {-8016, -5804}, {-7859, -6091}, {-7682, -6352}, {-7495, -6607}, {-7289, -6845}, {-7071, -7071}, {-6839, -7283}, {-6592, -7478}, {-6335, -7662}, {-6063, -7823}, {-5775, -7976}, {-5514, -8107}, {-5221, -8207}, {-4920, -8312}, {-4603, -8378}, {-4294, -8446}, {-4000, -8489}, {-3685, -8503}, {-3359, -8503}}}
assert.True(t, reflect.DeepEqual(solution, expected), "solution does not match expected")
}
// Test4 - Variable offset using sin of edge angle
func TestOffsetVariableCallback4(t *testing.T) {
const scale = 100
subject := goclipper2.Paths64{goclipper2.Ellipse64(goclipper2.Point64{X: 10 * scale, Y: 10 * scale}, 40*scale, 40*scale, 256)}
co := goclipper2.NewClipperOffset(0.0, 10.0, true, false)
co.AddPaths(subject, goclipper2.Round, goclipper2.RoundET)
var deltaFunc goclipper2.DeltaCallbackFunc = func(path *goclipper2.Path64, path_normals *goclipper2.PathD, curr_idx, prev_idx int) float64 {
sinEdge := (*path_normals)[curr_idx].Y
return sinEdge * sinEdge * 3 * scale
}
co.SetDeltaCallback(&deltaFunc)
solution := goclipper2.Paths64{}
co.Execute64(1.0, &solution)
var expected = goclipper2.Paths64{{{1101, -3298}, {1110, -3298}, {1208, -3294}, {1214, -3293}, {1312, -3286}, {1318, -3286}, {1416, -3276}, {1425, -3275}, {1523, -3263}, {1529, -3262}, {1626, -3246}, {1635, -3245}, {1731, -3227}, {1737, -3226}, {1833, -3206}, {1839, -3204}, {1934, -3181}, {1942, -3179}, {2037, -3153}, {2043, -3151}, {2138, -3123}, {2144, -3121}, {2236, -3090}, {2244, -3087}, {2337, -3054}, {2342, -3052}, {2434, -3016}, {2439, -3014}, {2530, -2975}, {2535, -2973}, {2624, -2931}, {2631, -2928}, {2719, -2884}, {2725, -2882}, {2811, -2836}, {2816, -2834}, {2902, -2787}, {2906, -2785}, {2990, -2732}, {2997, -2728}, {3081, -2675}, {3085, -2673}, {3165, -2618}, {3170, -2615}, {3251, -2559}, {3255, -2557}, {3332, -2496}, {3337, -2493}, {3416, -2434}, {3418, -2432}, {3492, -2366}, {3498, -2362}, {3573, -2299}, {3575, -2297}, {3647, -2230}, {3651, -2227}, {3721, -2157}, {3724, -2154}, {3793, -2084}, {3796, -2082}, {3862, -2008}, {3865, -2005}, {3932, -1933}, {3933, -1932}, {3996, -1856}, {3999, -1853}, {4061, -1776}, {4063, -1774}, {4122, -1696}, {4124, -1693}, {4181, -1612}, {4183, -1610}, {4240, -1530}, {4241, -1529}, {4293, -1445}, {4295, -1442}, {4349, -1359}, {4350, -1358}, {4399, -1272}, {4400, -1270}, {4449, -1185}, {4450, -1184}, {4496, -1096}, {4497, -1094}, {4542, -1008}, {4542, -1007}, {4582, -916}, {4583, -914}, {4624, -824}, {4625, -823}, {4663, -733}, {4664, -732}, {4700, -641}, {4701, -640}, {4733, -547}, {4734, -546}, {4766, -453}, {4766, -452}, {4796, -359}, {4796, -358}, {4824, -264}, {4824, -263}, {4850, -168}, {4850, -167}, {4874, -72}, {4896, 24}, {4915, 121}, {4933, 218}, {4949, 315}, {4962, 412}, {4974, 510}, {4983, 608}, {4990, 706}, {4995, 804}, {4999, 902}, {4994, 804}, {4987, 706}, {4977, 608}, {4965, 511}, {4970, 510}, {4965, 511}, {4949, 414}, {4957, 413}, {4949, 414}, {4931, 318}, {4911, 223}, {4887, 128}, {4861, 33}, {4833, -61}, {4801, -153}, {4768, -245}, {4732, -336}, {4694, -425}, {4652, -512}, {4609, -599}, {4563, -686}, {4517, -771}, {4466, -851}, {4413, -935}, {4360, -1012}, {4304, -1093}, {4246, -1167}, {4188, -1244}, {4122, -1318}, {4061, -1390}, {3997, -1458}, {3930, -1525}, {3862, -1591}, {3792, -1654}, {3721, -1720}, {3648, -1779}, {3575, -1839}, {3500, -1894}, {3419, -1951}, {3344, -2005}, {3268, -2051}, {3188, -2103}, {3107, -2148}, {3022, -2197}, {2943, -2238}, {2861, -2280}, {2778, -2316}, {2692, -2355}, {2606, -2391}, {2521, -2425}, {2436, -2455}, {2349, -2484}, {2261, -2512}, {2172, -2539}, {2084, -2562}, {1990, -2585}, {1906, -2604}, {1809, -2623}, {1727, -2638}, {1636, -2653}, {1539, -2666}, {1451, -2676}, {1368, -2684}, {1270, -2691}, {1178, -2696}, {1086, -2699}, {997, -2700}, {914, -2700}, {816, -2696}, {815, -2696}, {729, -2692}, {730, -2692}, {632, -2686}, {631, -2686}, {543, -2677}, {542, -2677}, {459, -2668}, {363, -2655}, {273, -2640}, {272, -2640}, {182, -2625}, {181, -2625}, {93, -2607}, {92, -2607}, {4, -2587}, {3, -2587}, {-86, -2566}, {-87, -2566}, {-173, -2542}, {-174, -2542}, {-262, -2516}, {-263, -2516}, {-350, -2489}, {-351, -2489}, {-438, -2461}, {-439, -2461}, {-518, -2432}, {-517, -2432}, {-609, -2396}, {-694, -2359}, {-695, -2359}, {-782, -2324}, {-783, -2324}, {-863, -2285}, {-947, -2244}, {-1026, -2201}, {-1025, -2201}, {-1112, -2156}, {-1190, -2106}, {-1191, -2106}, {-1274, -2060}, {-1349, -2007}, {-1350, -2007}, {-1429, -1954}, {-1505, -1901}, {-1506, -1901}, {-1577, -1846}, {-1576, -1846}, {-1654, -1786}, {-1724, -1723}, {-1798, -1660}, {-1867, -1596}, {-1936, -1530}, {-1937, -1530}, {-2003, -1464}, {-2066, -1393}, {-2065, -1393}, {-2133, -1321}, {-2191, -1248}, {-2190, -1248}, {-2253, -1172}, {-2309, -1096}, {-2308, -1096}, {-2366, -1016}, {-2418, -936}, {-2419, -936}, {-2474, -856}, {-2522, -773}, {-2521, -773}, {-2569, -688}, {-2568, -688}, {-2614, -602}, {-2613, -602}, {-2659, -516}, {-2658, -516}, {-2698, -427}, {-2736, -337}, {-2772, -246}, {-2806, -154}, {-2836, -62}, {-2864, 32}, {-2891, 127}, {-2913, 222}, {-2933, 317}, {-2941, 316}, {-2933, 317}, {-2952, 414}, {-2957, 413}, {-2952, 414}, {-2966, 510}, {-2979, 608}, {-2988, 706}, {-2995, 804}, {-2999, 902}, {-3000, 1000}, {-2999, 1098}, {-2994, 1196}, {-2987, 1294}, {-2977, 1392}, {-2965, 1489}, {-2970, 1490}, {-2965, 1489}, {-2949, 1586}, {-2957, 1587}, {-2949, 1586}, {-2931, 1682}, {-2911, 1777}, {-2887, 1872}, {-2861, 1967}, {-2833, 2061}, {-2801, 2153}, {-2802, 2154}, {-2768, 2245}, {-2732, 2336}, {-2694, 2425}, {-2653, 2513}, {-2652, 2512}, {-2609, 2599}, {-2564, 2685}, {-2518, 2770}, {-2467, 2852}, {-2466, 2851}, {-2414, 2934}, {-2360, 3012}, {-2305, 3092}, {-2247, 3168}, {-2246, 3167}, {-2188, 3244}, {-2125, 3315}, {-2062, 3389}, {-1998, 3459}, {-1997, 3458}, {-1930, 3525}, {-1862, 3591}, {-1792, 3654}, {-1721, 3720}, {-1649, 3780}, {-1648, 3779}, {-1576, 3840}, {-1575, 3839}, {-1501, 3895}, {-1500, 3894}, {-1419, 3951}, {-1420, 3952}, {-1344, 4005}, {-1269, 4052}, {-1268, 4051}, {-1188, 4103}, {-1108, 4149}, {-1107, 4148}, {-1022, 4197}, {-944, 4239}, {-943, 4238}, {-861, 4280}, {-779, 4317}, {-778, 4316}, {-692, 4355}, {-607, 4392}, {-606, 4391}, {-522, 4426}, {-521, 4425}, {-436, 4455}, {-350, 4485}, {-349, 4484}, {-261, 4512}, {-173, 4540}, {-172, 4539}, {-85, 4563}, {-84, 4562}, {10, 4585}, {9, 4586}, {93, 4605}, {94, 4604}, {191, 4623}, {190, 4624}, {273, 4638}, {364, 4653}, {461, 4666}, {549, 4676}, {548, 4677}, {631, 4685}, {632, 4684}, {730, 4691}, {729, 4692}, {822, 4696}, {821, 4697}, {914, 4699}, {913, 4700}, {1003, 4700}, {1086, 4700}, {1184, 4696}, {1184, 4697}, {1270, 4693}, {1270, 4692}, {1368, 4686}, {1368, 4687}, {1457, 4677}, {1457, 4678}, {1540, 4669}, {1637, 4655}, {1727, 4640}, {1727, 4641}, {1818, 4625}, {1818, 4626}, {1907, 4607}, {1907, 4608}, {1996, 4587}, {1996, 4588}, {2086, 4566}, {2086, 4567}, {2173, 4542}, {2173, 4543}, {2262, 4516}, {2262, 4517}, {2350, 4489}, {2350, 4490}, {2438, 4461}, {2438, 4462}, {2517, 4433}, {2517, 4432}, {2609, 4396}, {2694, 4359}, {2694, 4360}, {2782, 4324}, {2782, 4325}, {2863, 4285}, {2947, 4244}, {3029, 4199}, {3112, 4156}, {3190, 4106}, {3190, 4107}, {3274, 4060}, {3349, 4007}, {3349, 4008}, {3429, 3954}, {3505, 3901}, {3505, 3902}, {3579, 3844}, {3654, 3786}, {3724, 3723}, {3798, 3660}, {3867, 3596}, {3936, 3530}, {3936, 3531}, {4003, 3464}, {4066, 3392}, {4133, 3321}, {4191, 3247}, {4253, 3172}, {4309, 3095}, {4366, 3016}, {4418, 2936}, {4418, 2937}, {4474, 2856}, {4522, 2772}, {4569, 2687}, {4614, 2601}, {4658, 2516}, {4698, 2427}, {4736, 2337}, {4772, 2246}, {4806, 2154}, {4836, 2062}, {4864, 1968}, {4891, 1873}, {4913, 1778}, {4933, 1683}, {4941, 1684}, {4933, 1683}, {4952, 1586}, {4957, 1587}, {4952, 1586}, {4966, 1490}, {4979, 1392}, {4988, 1294}, {4995, 1196}, {4999, 1098}, {5000, 1000}, {4999, 1098}, {4996, 1196}, {4991, 1294}, {4985, 1392}, {4975, 1491}, {4965, 1588}, {4951, 1686}, {4935, 1782}, {4935, 1783}, {4919, 1879}, {4919, 1880}, {4899, 1977}, {4877, 2073}, {4855, 2169}, {4854, 2169}, {4828, 2265}, {4800, 2360}, {4770, 2454}, {4770, 2455}, {4740, 2548}, {4740, 2550}, {4705, 2642}, {4705, 2643}, {4669, 2734}, {4668, 2735}, {4629, 2825}, {4628, 2826}, {4591, 2918}, {4590, 2921}, {4547, 3009}, {4546, 3010}, {4503, 3098}, {4502, 3100}, {4454, 3187}, {4453, 3188}, {4407, 3275}, {4406, 3277}, {4353, 3360}, {4352, 3362}, {4304, 3448}, {4301, 3451}, {4245, 3532}, {4244, 3533}, {4189, 3615}, {4187, 3618}, {4131, 3698}, {4128, 3701}, {4068, 3779}, {4066, 3781}, {4005, 3859}, {4002, 3862}, {3936, 3935}, {3935, 3936}, {3871, 4012}, {3868, 4015}, {3800, 4086}, {3797, 4089}, {3730, 4160}, {3726, 4164}, {3657, 4233}, {3652, 4236}, {3578, 4301}, {3576, 4302}, {3504, 4371}, {3498, 4375}, {3421, 4435}, {3418, 4437}, {3342, 4500}, {3337, 4504}, {3258, 4561}, {3254, 4563}, {3174, 4621}, {3169, 4624}, {3087, 4678}, {3083, 4680}, {3002, 4736}, {2994, 4740}, {2908, 4789}, {2904, 4791}, {2819, 4838}, {2814, 4841}, {2727, 4886}, {2721, 4889}, {2634, 4934}, {2626, 4937}, {2537, 4977}, {2531, 4980}, {2441, 5018}, {2435, 5020}, {2344, 5055}, {2338, 5057}, {2245, 5092}, {2238, 5094}, {2144, 5125}, {2138, 5126}, {2044, 5154}, {2038, 5156}, {1943, 5183}, {1935, 5184}, {1839, 5207}, {1833, 5208}, {1738, 5228}, {1732, 5229}, {1635, 5248}, {1626, 5249}, {1529, 5264}, {1523, 5264}, {1425, 5277}, {1416, 5278}, {1318, 5287}, {1312, 5287}, {1214, 5294}, {1208, 5294}, {1110, 5299}, {1101, 5299}, {1003, 5300}, {997, 5300}, {899, 5298}, {890, 5298}, {792, 5294}, {786, 5293}, {688, 5286}, {682, 5286}, {584, 5276}, {575, 5275}, {477, 5263}, {471, 5262}, {374, 5246}, {365, 5245}, {269, 5227}, {263, 5226}, {167, 5206}, {161, 5204}, {66, 5181}, {58, 5179}, {-37, 5153}, {-43, 5151}, {-138, 5123}, {-144, 5121}, {-236, 5090}, {-244, 5087}, {-337, 5054}, {-342, 5052}, {-434, 5016}, {-439, 5014}, {-530, 4975}, {-535, 4973}, {-624, 4931}, {-631, 4928}, {-719, 4884}, {-725, 4882}, {-811, 4836}, {-816, 4834}, {-902, 4787}, {-906, 4785}, {-990, 4732}, {-997, 4728}, {-1081, 4675}, {-1085, 4673}, {-1165, 4618}, {-1170, 4615}, {-1251, 4559}, {-1255, 4557}, {-1332, 4496}, {-1337, 4493}, {-1416, 4434}, {-1418, 4432}, {-1492, 4366}, {-1498, 4362}, {-1573, 4299}, {-1575, 4297}, {-1647, 4230}, {-1651, 4227}, {-1721, 4157}, {-1724, 4154}, {-1793, 4084}, {-1796, 4082}, {-1862, 4008}, {-1865, 4005}, {-1932, 3933}, {-1933, 3932}, {-1996, 3856}, {-1999, 3853}, {-2061, 3776}, {-2063, 3774}, {-2122, 3696}, {-2124, 3693}, {-2181, 3612}, {-2183, 3610}, {-2240, 3530}, {-2241, 3529}, {-2293, 3445}, {-2295, 3442}, {-2349, 3359}, {-2350, 3358}, {-2399, 3272}, {-2400, 3270}, {-2449, 3185}, {-2450, 3184}, {-2496, 3096}, {-2497, 3094}, {-2542, 3008}, {-2542, 3007}, {-2582, 2916}, {-2583, 2914}, {-2624, 2824}, {-2625, 2823}, {-2663, 2733}, {-2664, 2732}, {-2700, 2641}, {-2701, 2640}, {-2733, 2547}, {-2734, 2546}, {-2766, 2453}, {-2766, 2452}, {-2796, 2359}, {-2796, 2358}, {-2824, 2264}, {-2824, 2263}, {-2850, 2168}, {-2850, 2167}, {-2874, 2072}, {-2896, 1976}, {-2915, 1879}, {-2933, 1782}, {-2949, 1685}, {-2962, 1588}, {-2974, 1490}, {-2983, 1392}, {-2990, 1294}, {-2995, 1196}, {-2999, 1098}, {-3000, 1000}, {-2999, 902}, {-2996, 804}, {-2991, 706}, {-2985, 608}, {-2975, 509}, {-2965, 412}, {-2951, 314}, {-2935, 218}, {-2935, 217}, {-2919, 121}, {-2919, 120}, {-2899, 23}, {-2877, -73}, {-2855, -169}, {-2854, -169}, {-2828, -265}, {-2800, -360}, {-2770, -454}, {-2770, -455}, {-2740, -548}, {-2740, -550}, {-2705, -642}, {-2705, -643}, {-2669, -734}, {-2668, -735}, {-2629, -825}, {-2628, -826}, {-2591, -918}, {-2590, -921}, {-2547, -1009}, {-2546, -1010}, {-2503, -1098}, {-2502, -1100}, {-2454, -1187}, {-2453, -1188}, {-2407, -1275}, {-2406, -1277}, {-2353, -1360}, {-2352, -1362}, {-2304, -1448}, {-2301, -1451}, {-2245, -1532}, {-2244, -1533}, {-2189, -1615}, {-2187, -1618}, {-2131, -1698}, {-2128, -1701}, {-2068, -1779}, {-2066, -1781}, {-2005, -1859}, {-2002, -1862}, {-1936, -1935}, {-1935, -1936}, {-1871, -2012}, {-1868, -2015}, {-1800, -2086}, {-1797, -2089}, {-1730, -2160}, {-1726, -2164}, {-1657, -2233}, {-1652, -2236}, {-1578, -2301}, {-1576, -2302}, {-1504, -2371}, {-1498, -2375}, {-1421, -2435}, {-1418, -2437}, {-1342, -2500}, {-1337, -2504}, {-1258, -2561}, {-1254, -2563}, {-1174, -2621}, {-1169, -2624}, {-1087, -2678}, {-1083, -2680}, {-1002, -2736}, {-994, -2740}, {-908, -2789}, {-904, -2791}, {-819, -2838}, {-814, -2841}, {-727, -2886}, {-721, -2889}, {-634, -2934}, {-626, -2937}, {-537, -2977}, {-531, -2980}, {-441, -3018}, {-435, -3020}, {-344, -3055}, {-338, -3057}, {-245, -3092}, {-238, -3094}, {-144, -3125}, {-138, -3126}, {-44, -3154}, {-38, -3156}, {57, -3183}, {65, -3184}, {161, -3207}, {167, -3208}, {262, -3228}, {268, -3229}, {365, -3248}, {374, -3249}, {471, -3264}, {477, -3264}, {575, -3277}, {584, -3278}, {682, -3287}, {688, -3287}, {786, -3294}, {792, -3294}, {890, -3299}, {899, -3299}, {997, -3300}, {1003, -3300}}}
assert.True(t, reflect.DeepEqual(solution, expected), "solution does not match expected")
}
// Test5 - Variable offset on a line with quadratic delta
func TestOffsetVariableCallback5(t *testing.T) {
subject := goclipper2.Paths64{goclipper2.MakePath64(0, 0, 20, 0, 40, 0, 60, 0, 80, 0, 100, 0)}
co := goclipper2.NewClipperOffset(0.0, 10.0, true, false)
co.AddPaths(subject, goclipper2.Round, goclipper2.Butt)
var deltaFunc goclipper2.DeltaCallbackFunc = func(path *goclipper2.Path64, path_normals *goclipper2.PathD, curr_idx, prev_idx int) float64 {
return float64(curr_idx*curr_idx) + 10
}
co.SetDeltaCallback(&deltaFunc)
solution := goclipper2.Paths64{}
co.Execute64(1.0, &solution)
var expected = goclipper2.Paths64{{{100, 0}, {80, 26}, {60, 19}, {40, 14}, {20, 11}, {0, 0}, {20, -11}, {40, -14}, {60, -19}, {80, -26}}}
assert.True(t, reflect.DeepEqual(solution, expected), "solution does not match expected")
}