block.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. // Copyright 2015 by caixw, All rights reserved
  2. // Use of this source code is governed by a MIT
  3. // license that can be found in the LICENSE file.
  4. package identicon
  5. import (
  6. "image"
  7. "sync"
  8. )
  9. var pool = sync.Pool{
  10. New: func() interface{} { return make([]float64, 0, 10) },
  11. }
  12. var (
  13. // 可以出现在中间的方块,一般为了美观,都是对称图像。
  14. centerBlocks = []blockFunc{b0, b1, b2, b3}
  15. // 所有方块
  16. blocks = []blockFunc{b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16}
  17. )
  18. // 所有block函数的类型
  19. type blockFunc func(img *image.Paletted, x, y, size float64, angle int)
  20. // 将多边形points旋转angle个角度,然后输出到img上,起点为x,y坐标
  21. func drawBlock(img *image.Paletted, x, y, size float64, angle int, points []float64) {
  22. if angle > 0 { // 0角度不需要转换
  23. // 中心坐标与x,y的距离,方便下面指定中心坐标(x+m,y+m),
  24. // 0.5的偏移值不能少,否则坐靠右,非正中央
  25. m := size/2 - 0.5
  26. rotate(points, x+m, y+m, angle)
  27. }
  28. for i := x; i < x+size; i++ {
  29. for j := y; j < y+size; j++ {
  30. if pointInPolygon(i, j, points) {
  31. img.SetColorIndex(int(i), int(j), 1)
  32. }
  33. }
  34. }
  35. }
  36. // 全空白
  37. //
  38. // --------
  39. // | |
  40. // | |
  41. // | |
  42. // --------
  43. func b0(img *image.Paletted, x, y, size float64, angle int) {
  44. }
  45. // 全填充正方形
  46. //
  47. // --------
  48. // |######|
  49. // |######|
  50. // |######|
  51. // --------
  52. func b1(img *image.Paletted, x, y, size float64, angle int) {
  53. isize := int(size)
  54. ix := int(x)
  55. iy := int(y)
  56. for i := ix + 1; i < ix+isize; i++ {
  57. for j := iy + 1; j < iy+isize; j++ {
  58. img.SetColorIndex(i, j, 1)
  59. }
  60. }
  61. }
  62. // 中间小方块
  63. // ----------
  64. // | |
  65. // | #### |
  66. // | #### |
  67. // | |
  68. // ----------
  69. func b2(img *image.Paletted, x, y, size float64, angle int) {
  70. l := size / 4
  71. x = x + l
  72. y = y + l
  73. for i := x; i < x+2*l; i++ {
  74. for j := y; j < y+2*l; j++ {
  75. img.SetColorIndex(int(i), int(j), 1)
  76. }
  77. }
  78. }
  79. // 菱形
  80. //
  81. // ---------
  82. // | # |
  83. // | ### |
  84. // | ##### |
  85. // |#######|
  86. // | ##### |
  87. // | ### |
  88. // | # |
  89. // ---------
  90. func b3(img *image.Paletted, x, y, size float64, angle int) {
  91. m := size / 2
  92. points := pool.Get().([]float64)[:0]
  93. drawBlock(img, x, y, size, 0, append(points,
  94. x+m, y,
  95. x+size, y+m,
  96. x+m, y+size,
  97. x, y+m,
  98. x+m, y,
  99. ))
  100. pool.Put(points)
  101. }
  102. // b4
  103. //
  104. // -------
  105. // |#####|
  106. // |#### |
  107. // |### |
  108. // |## |
  109. // |# |
  110. // |------
  111. func b4(img *image.Paletted, x, y, size float64, angle int) {
  112. points := pool.Get().([]float64)[:0]
  113. drawBlock(img, x, y, size, angle, append(points,
  114. x, y,
  115. x+size, y,
  116. x, y+size,
  117. x, y,
  118. ))
  119. pool.Put(points)
  120. }
  121. // b5
  122. //
  123. // ---------
  124. // | # |
  125. // | ### |
  126. // | ##### |
  127. // |#######|
  128. func b5(img *image.Paletted, x, y, size float64, angle int) {
  129. points := pool.Get().([]float64)[:0]
  130. m := size / 2
  131. drawBlock(img, x, y, size, angle, append(points,
  132. x+m, y,
  133. x+size,
  134. y+size,
  135. x, y+size,
  136. x+m, y,
  137. ))
  138. pool.Put(points)
  139. }
  140. // b6 矩形
  141. //
  142. // --------
  143. // |### |
  144. // |### |
  145. // |### |
  146. // --------
  147. func b6(img *image.Paletted, x, y, size float64, angle int) {
  148. points := pool.Get().([]float64)[:0]
  149. m := size / 2
  150. drawBlock(img, x, y, size, angle, append(points,
  151. x, y,
  152. x+m, y,
  153. x+m, y+size,
  154. x, y+size,
  155. x, y,
  156. ))
  157. pool.Put(points)
  158. }
  159. // b7 斜放的锥形
  160. //
  161. // ---------
  162. // | # |
  163. // | ## |
  164. // | #####|
  165. // | ####|
  166. // |--------
  167. func b7(img *image.Paletted, x, y, size float64, angle int) {
  168. points := pool.Get().([]float64)[:0]
  169. m := size / 2
  170. drawBlock(img, x, y, size, angle, append(points,
  171. x, y,
  172. x+size, y+m,
  173. x+size, y+size,
  174. x+m, y+size,
  175. x, y,
  176. ))
  177. pool.Put(points)
  178. }
  179. // b8 三个堆叠的三角形
  180. //
  181. // -----------
  182. // | # |
  183. // | ### |
  184. // | ##### |
  185. // | # # |
  186. // | ### ### |
  187. // |#########|
  188. // -----------
  189. func b8(img *image.Paletted, x, y, size float64, angle int) {
  190. points := pool.Get().([]float64)[:0]
  191. m := size / 2
  192. mm := m / 2
  193. // 顶部三角形
  194. drawBlock(img, x, y, size, angle, append(points,
  195. x+m, y,
  196. x+3*mm, y+m,
  197. x+mm, y+m,
  198. x+m, y,
  199. ))
  200. // 底下左边
  201. drawBlock(img, x, y, size, angle, append(points[:0],
  202. x+mm, y+m,
  203. x+m, y+size,
  204. x, y+size,
  205. x+mm, y+m,
  206. ))
  207. // 底下右边
  208. drawBlock(img, x, y, size, angle, append(points[:0],
  209. x+3*mm, y+m,
  210. x+size, y+size,
  211. x+m, y+size,
  212. x+3*mm, y+m,
  213. ))
  214. pool.Put(points)
  215. }
  216. // b9 斜靠的三角形
  217. //
  218. // ---------
  219. // |# |
  220. // | #### |
  221. // | #####|
  222. // | #### |
  223. // | # |
  224. // ---------
  225. func b9(img *image.Paletted, x, y, size float64, angle int) {
  226. points := pool.Get().([]float64)[:0]
  227. m := size / 2
  228. drawBlock(img, x, y, size, angle, append(points,
  229. x, y,
  230. x+size, y+m,
  231. x+m, y+size,
  232. x, y,
  233. ))
  234. pool.Put(points)
  235. }
  236. // b10
  237. //
  238. // ----------
  239. // | ####|
  240. // | ### |
  241. // | ## |
  242. // | # |
  243. // |#### |
  244. // |### |
  245. // |## |
  246. // |# |
  247. // ----------
  248. func b10(img *image.Paletted, x, y, size float64, angle int) {
  249. points := pool.Get().([]float64)[:0]
  250. m := size / 2
  251. drawBlock(img, x, y, size, angle, append(points,
  252. x+m, y,
  253. x+size, y,
  254. x+m, y+m,
  255. x+m, y,
  256. ))
  257. drawBlock(img, x, y, size, angle, append(points[:0],
  258. x, y+m,
  259. x+m, y+m,
  260. x, y+size,
  261. x, y+m,
  262. ))
  263. pool.Put(points)
  264. }
  265. // b11 左上角1/4大小的方块
  266. //
  267. // ----------
  268. // |#### |
  269. // |#### |
  270. // |#### |
  271. // | |
  272. // | |
  273. // ----------
  274. func b11(img *image.Paletted, x, y, size float64, angle int) {
  275. points := pool.Get().([]float64)[:0]
  276. m := size / 2
  277. drawBlock(img, x, y, size, angle, append(points,
  278. x, y,
  279. x+m, y,
  280. x+m, y+m,
  281. x, y+m,
  282. x, y,
  283. ))
  284. pool.Put(points)
  285. }
  286. // b12
  287. //
  288. // -----------
  289. // | |
  290. // | |
  291. // |#########|
  292. // | ##### |
  293. // | # |
  294. // -----------
  295. func b12(img *image.Paletted, x, y, size float64, angle int) {
  296. points := pool.Get().([]float64)[:0]
  297. m := size / 2
  298. drawBlock(img, x, y, size, angle, append(points,
  299. x, y+m,
  300. x+size, y+m,
  301. x+m, y+size,
  302. x, y+m,
  303. ))
  304. pool.Put(points)
  305. }
  306. // b13
  307. //
  308. // -----------
  309. // | |
  310. // | |
  311. // | # |
  312. // | ##### |
  313. // |#########|
  314. // -----------
  315. func b13(img *image.Paletted, x, y, size float64, angle int) {
  316. points := pool.Get().([]float64)[:0]
  317. m := size / 2
  318. drawBlock(img, x, y, size, angle, append(points,
  319. x+m, y+m,
  320. x+size, y+size,
  321. x, y+size,
  322. x+m, y+m,
  323. ))
  324. pool.Put(points)
  325. }
  326. // b14
  327. //
  328. // ---------
  329. // | # |
  330. // | ### |
  331. // |#### |
  332. // | |
  333. // | |
  334. // ---------
  335. func b14(img *image.Paletted, x, y, size float64, angle int) {
  336. points := pool.Get().([]float64)[:0]
  337. m := size / 2
  338. drawBlock(img, x, y, size, angle, append(points,
  339. x+m, y,
  340. x+m, y+m,
  341. x, y+m,
  342. x+m, y,
  343. ))
  344. pool.Put(points)
  345. }
  346. // b15
  347. //
  348. // ----------
  349. // |##### |
  350. // |### |
  351. // |# |
  352. // | |
  353. // | |
  354. // ----------
  355. func b15(img *image.Paletted, x, y, size float64, angle int) {
  356. points := pool.Get().([]float64)[:0]
  357. m := size / 2
  358. drawBlock(img, x, y, size, angle, append(points,
  359. x, y,
  360. x+m, y,
  361. x, y+m,
  362. x, y,
  363. ))
  364. pool.Put(points)
  365. }
  366. // b16
  367. //
  368. // ---------
  369. // | # |
  370. // | ##### |
  371. // |#######|
  372. // | # |
  373. // | ##### |
  374. // |#######|
  375. // ---------
  376. func b16(img *image.Paletted, x, y, size float64, angle int) {
  377. points := pool.Get().([]float64)[:0]
  378. m := size / 2
  379. drawBlock(img, x, y, size, angle, append(points,
  380. x+m, y,
  381. x+size, y+m,
  382. x, y+m,
  383. x+m, y,
  384. ))
  385. drawBlock(img, x, y, size, angle, append(points[:0],
  386. x+m, y+m,
  387. x+size, y+size,
  388. x, y+size,
  389. x+m, y+m,
  390. ))
  391. pool.Put(points)
  392. }