Advertisement
Guest User

Untitled

a guest
Oct 14th, 2015
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.90 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4. "bufio"
  5. "os"
  6. "fmt"
  7. "strconv"
  8. "math"
  9. "sort"
  10. )
  11.  
  12. func getXcartesian(radius, angle float64) (coordinate float64){
  13. return radius * math.Cos(angle * (math.Pi / 180))
  14. }
  15. func getYcartesian(radius, angle float64) (coordinate float64){
  16. return radius * math.Sin(angle * (math.Pi / 180))
  17. }
  18.  
  19. func getLines(filename string) ([]string) {
  20. lines := []string{}
  21. f, err := os.Open(filename)
  22. defer f.Close()
  23. if err != nil {
  24. fmt.Println(err)
  25. os.Exit(1)
  26. }
  27. scanner := bufio.NewScanner(f)
  28. scanner.Split(bufio.ScanLines)
  29. inEntities := false
  30. // extract all the lines of entities
  31. for scanner.Scan() {
  32. switch scanner.Text() {
  33. case "ENTITIES":
  34. inEntities = true
  35. case "ENDSEC":
  36. inEntities = false
  37. }
  38. if inEntities {
  39. lines = append(lines, scanner.Text())
  40. }
  41. }
  42. return lines
  43. }
  44.  
  45. func getEnt(list []string, e []Ent) ([]Ent){
  46. // add error handling
  47. group := ""
  48. count := 0
  49. for i := range list {
  50. if len(group) > 0 {
  51. switch group {
  52. case " 0":
  53. if len(e) > 0 {count++}
  54. e = append(e, Ent{})
  55. e[count].G0 = list[i]
  56. case " 8":
  57. e[count].G8 = list[i]
  58. case " 10":
  59. e[count].G10, _ = strconv.ParseFloat(list[i],64)
  60. case " 11":
  61. e[count].G11, _ = strconv.ParseFloat(list[i],64)
  62. case " 20":
  63. e[count].G20, _ = strconv.ParseFloat(list[i],64)
  64. case " 21":
  65. e[count].G21, _ = strconv.ParseFloat(list[i],64)
  66. case " 30":
  67. e[count].G30, _ = strconv.ParseFloat(list[i],64)
  68. case " 31":
  69. e[count].G31, _ = strconv.ParseFloat(list[i],64)
  70. case " 40":
  71. e[count].G40, _ = strconv.ParseFloat(list[i],64)
  72. case " 50":
  73. e[count].G50, _ = strconv.ParseFloat(list[i],64)
  74. case " 51":
  75. e[count].G51, _ = strconv.ParseFloat(list[i],64)
  76. }
  77. group = ""
  78. }
  79. switch list[i] { // trigger when a group is found
  80. case " 0", " 8", " 10", " 11", " 20", " 21",
  81. " 30", " 31", " 40", " 50", " 51":
  82. group = list[i]
  83. }
  84. }
  85. return e
  86. }
  87.  
  88. func findEndPoints (e []Ent) ([]Ent){
  89. // add error handling
  90. for i := range e {
  91. switch e[i].G0 {
  92. case "ARC": // get the X and Y end points
  93. e[i].Xs = getXcartesian(e[i].G40, e[i].G50) + e[i].G10
  94. e[i].Xe = getXcartesian(e[i].G40, e[i].G51) + e[i].G10
  95. e[i].Ys = getYcartesian(e[i].G40, e[i].G50) + e[i].G20
  96. e[i].Ye = getYcartesian(e[i].G40, e[i].G51) + e[i].G20
  97. case "LINE":
  98. e[i].Xs = e[i].G10
  99. e[i].Ys = e[i].G20
  100. e[i].Zs = e[i].G30
  101. e[i].Xe = e[i].G11
  102. e[i].Ye = e[i].G21
  103. e[i].Zs = e[i].G31
  104. case "CIRCLE": // if it is a circle it must be the only entity on that layer
  105. fmt.Println("Circle")
  106. }
  107. }
  108. return e
  109. }
  110.  
  111. // find the matching start points for each entity and assign index
  112. func findIndex(s int, t float64, e []Ent) ([]Ent) {
  113. // add error handling
  114. xe := e[s].Xe
  115. ye := e[s].Ye
  116. index := 1
  117. for skip, ent := range e {
  118. fmt.Printf("Xs=%f Ys=%f Xe=%f Ye=%f\n",ent.Xs, ent.Ys, ent.Xe, ent.Ye)
  119. if skip != s {
  120. for i := range e {
  121. if math.Abs(e[i].Xs - xe) < t && math.Abs(e[i].Ys - ye) < t {
  122. e[i].Index = index
  123. index++
  124. xe = e[i].Xe
  125. ye = e[i].Ye
  126. fmt.Println("match found")
  127. break
  128. }
  129. }
  130. }
  131. }
  132. return e
  133. }
  134.  
  135. type Ent struct {
  136. Index int
  137. G0, G8 string
  138. G10, G11, G20, G21, G30, G31, G40, G50, G51,
  139. Xs, Xe, Ys, Ye, Zs, Ze float64
  140. }
  141.  
  142. type ByIndex []Ent
  143.  
  144. func (a ByIndex) Len() int { return len(a) }
  145. func (a ByIndex) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
  146. func (a ByIndex) Less(i, j int) bool { return a[i].Index < a[j].Index }
  147.  
  148. func genGcode (e []Ent) {
  149. /*
  150. need to figure out if the start point of first entity and the end point
  151. of the last entity are the same if so then make the last move to the
  152. start point.
  153. */
  154. xe, ye := e[0].Xe, e[0].Ye
  155. xo, yo := 0.0, 0.0
  156. feed := 25.0
  157. outfile := "/home/john/linuxcnc/nc_files/output.ngc"
  158. f, err := os.Create(outfile)
  159. if err != nil {
  160. fmt.Println(err)
  161. os.Exit(1)
  162. }
  163. defer f.Close()
  164.  
  165. fmt.Fprintf(f, "G0 X%f Y%f\n", e[0].Xs, e[0].Ys)
  166. fmt.Fprintf(f, "F%.1f\n",feed)
  167. for _, ent := range e {
  168. switch ent.G0 {
  169. case "LINE":
  170. fmt.Fprintf(f, "G1 X%.4f Y%.4f\n", ent.G11, ent.G21)
  171. xe = ent.Xe
  172. ye = ent.Ye
  173. case "ARC": // need some smarts here, offset depends on last xy position
  174. xo = ent.G10 - xe
  175. yo = ent.G20 - ye
  176. fmt.Fprintf(f, "G3 X%.4f Y%.4f I%.4f J%.4f\n", ent.Xe, ent.Ye, xo, yo)
  177. xe = ent.Xe
  178. ye = ent.Ye
  179. case "CIRCLE":
  180. fmt.Println("Circle")
  181. }
  182. }
  183. fmt.Fprintf(f, "M2")
  184. }
  185.  
  186. func main(){
  187. var file = ""
  188. if len(os.Args) > 1 {
  189. file = os.Args[1]
  190. } else {
  191. file = "square.dxf"
  192. }
  193. pwd, _ := os.Getwd()
  194. fmt.Println("pwd", pwd)
  195. var entities []Ent
  196. lines := getLines(file)
  197. entities = getEnt(lines, entities)
  198. entities = findEndPoints(entities)
  199. start := 1
  200. tolerance := 0.0000001
  201. entities = findIndex(start, tolerance, entities)
  202. for i := range entities {
  203. fmt.Println(entities[i])
  204. }
  205. sort.Sort(ByIndex(entities))
  206. genGcode(entities)
  207. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement