Advertisement
Guest User

Untitled

a guest
Feb 24th, 2020
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.01 KB | None | 0 0
  1. using Makie
  2. using GeometryTypes
  3.  
  4. println("---------------------------NEW RUN---------------------------")
  5. println()
  6.  
  7. # inputStr = "(((a+b)*(c+(d-(-b))))*a)"
  8. # inputStr = "(((a+b)*(c+(d-(-b))))-(a*(d-(-b))))"
  9. # inputStr = "(a+b)"
  10. inputStr = "(((a+b)*(c+(d+b)))-(a*(d+b)))"
  11.  
  12. println(inputStr)
  13. println()
  14.  
  15. openBranch = "("
  16. closeBranch = ")"
  17.  
  18. const SHIRINA = 1500 # ширина (x)
  19. const VISOTA = 800 # высота (y)
  20. RADIUS = 30
  21.  
  22. # sign - знак выражения (+,-,*,/)
  23. # arg1 - первый аргумент
  24. # arg2 - второй аргумент
  25. mutable struct Bracket
  26. sign
  27. arg1
  28. arg2
  29. end
  30.  
  31. # index - номер
  32. # x - координата x
  33. # y - координата y
  34. # text - текст в вершине
  35. # left - левая вершина (может отсутствовать, в этом случае равна 0)
  36. # right - правая вершина
  37. mutable struct VertexGraph
  38. index
  39. x
  40. y
  41. text
  42. left
  43. right
  44. end
  45.  
  46. # Содержит выражения по уровням
  47. allLevelsExpression = Array{String,1}[]
  48.  
  49. # Выводит на экран массив allLevelsExpression
  50. function allLevelsExpressionPrint()
  51. println("allLevelsExpression:")
  52. for i = 1:length(allLevelsExpression)
  53. println("level_$i:")
  54. println(allLevelsExpression[i])
  55. end
  56. end
  57.  
  58. # Содержит "Bracket-ы" по уровням
  59. allLevelsBracket = Array{Bracket,1}[]
  60.  
  61. # Выводит на экран массив allLevelsBracket
  62. function allLevelsBracketPrint()
  63. println("allLevelsBracket:")
  64. for i = 1:length(allLevelsBracket)
  65. println("level_$i:")
  66. println(allLevelsBracket[i])
  67. end
  68. end
  69.  
  70. # Содержит все вершины графа
  71. allVertex = []
  72.  
  73. # Выводит на экран массив allVertex
  74. function allVertexPrint()
  75. println("allVertex:")
  76. for i = 1:length(allVertex)
  77. println(allVertex[i])
  78. end
  79. end
  80.  
  81. # Содержит текущие вершины графа
  82. curentVertex = []
  83.  
  84. # Выводит на экран массив curentVertex
  85. function curentVertexPrint()
  86. println("curentVertex:")
  87. for i = 1:length(curentVertex)
  88. println(curentVertex[i])
  89. end
  90. end
  91.  
  92. # разбивает строку вида (arg1[+*-/]arg2) на аргументы, знак и заносит их в структуру
  93. # (arg1 может отсутствовать (Например "(-b)"), в таком случае bracket.arg1 = "")
  94. function bracketParse(str)
  95. flag = 0
  96. bracket = Bracket("", "", "")
  97.  
  98. for i = 1:length(str)
  99. symbol = SubString(str, i, i)
  100.  
  101. if symbol == openBranch
  102. flag = 1
  103. elseif occursin(r"[+*-/]", symbol)
  104. flag = 2
  105. bracket.sign = symbol
  106. elseif symbol == closeBranch
  107. break
  108. elseif flag == 1
  109. bracket.arg1 = bracket.arg1 * symbol
  110. elseif flag == 2
  111. bracket.arg2 = bracket.arg2 * symbol
  112. end
  113.  
  114. end
  115.  
  116. return bracket
  117.  
  118. end
  119.  
  120. # из строки вида "l_levelNubmer_bracketNumber" вытаскивает и возвращает значения levelNubmer и bracketNumber
  121. function levelNameParse(str)
  122. # начинаем с 3 символа, т.к. первые два это "l_"
  123. levelString = "";
  124. bracketNubmerString = "";
  125.  
  126. indexUnderscore = 0;
  127. for i = 3:length(str)
  128. symbol = SubString(str, i, i)
  129. if symbol == "_"
  130. indexUnderscore = i
  131. break
  132. end
  133. end
  134. levelString = SubString(str, 3, indexUnderscore - 1)
  135. bracketNubmerString = SubString(str, indexUnderscore + 1, length(str))
  136.  
  137. levelInt = parse(Int, levelString)
  138. bracketNumberInt = parse(Int, bracketNubmerString)
  139.  
  140. levelInt, bracketNumberInt
  141. end
  142.  
  143. # Проверяет наличие символа в массиве
  144. function checkSymbolInArray(arr, symbol)
  145. for i = 1:length(arr)
  146. arrSymbol = arr[i]
  147. if symbol == arrSymbol
  148. return true
  149. end
  150. end
  151. return false
  152. end
  153.  
  154. # Проверяет наличие Bracket-а в массиве
  155. function checkBracketInArray(arr, bracket)
  156. for i = 1:length(arr)
  157. bracketInArray = arr[i]
  158. if bracketInArray.sign == bracket.sign &&
  159. bracketInArray.arg1 == bracket.arg1 &&
  160. bracketInArray.arg2 == bracket.arg2
  161. return true
  162. end
  163. end
  164. return false
  165. end
  166.  
  167. # Возвращает номера детей элемента по индексу из массива allVertex
  168. function checkChildrenInAllVertex(index)
  169. v = allVertex[getNumberVertexInAllVertexByIndex(index)]
  170. return v.left, v.right
  171. end
  172.  
  173. # Возвращает позицию элемента по index (атрибут) в массиве allVertex
  174. # Если нужного значения в массиве нет, возвращает -1
  175. function getNumberVertexInAllVertexByIndex(index)
  176. for i = 1:length(allVertex)
  177. if allVertex[i].index == index
  178. return i
  179. end
  180. end
  181. return -1
  182. end
  183.  
  184. # Возвращает позицию элемента по index (атрибут) в массиве curentVertex
  185. # Если нужного значения в массиве нет, возвращает -1
  186. function getNumberVertexInCurentVertexByIndex(index)
  187. for i = 1:length(curentVertex)
  188. if curentVertex[i].index == index
  189. return i
  190. end
  191. end
  192. return -1
  193. end
  194.  
  195. # Удаляет из массива curentVertex все элементы, где совпадает index
  196. function deleteFromCurentVertexByIndex(index)
  197. curentVertexCopy = []
  198. for i = 1:length(curentVertex)
  199. if curentVertex[i].index != index
  200. push!(curentVertexCopy, curentVertex[i])
  201. end
  202. end
  203. global curentVertex = curentVertexCopy
  204. end
  205.  
  206. # Проверяет, лежит ли точка (x, y) внутри круга с центром в точке (xc, yc) и радиусом (радиус задан как глобальная константа)
  207. function checkVertexInCircle(x, y, xc, yc)
  208. if (x - xc) ^ 2 + (y - yc) ^ 2 <= RADIUS ^ 2
  209. return true
  210. else
  211. return false
  212. end
  213. end
  214.  
  215. # TODO добавить, что элементы могут быть многозначными
  216. # Вытаскивае все "буквы" из строки и заменяет их на "l_1_i", где i - порядок встретивовшегося элемента
  217. function level1(str)
  218.  
  219. levelOneArrayExpression = String[]
  220.  
  221. for i = 1:length(str)
  222. symbol = SubString(str, i, i)
  223.  
  224. if (occursin(r"[a-z]|[A-Z]", symbol))
  225. if !checkSymbolInArray(levelOneArrayExpression, symbol)
  226. push!(levelOneArrayExpression, string(symbol))
  227. end
  228. end
  229.  
  230. end
  231.  
  232. #добавляем в массив allLevelsExpression, первый уровень (т.е. обычные элементы)
  233. push!(allLevelsExpression, levelOneArrayExpression)
  234.  
  235. #заменяем все элементы строки на l_НомерУровня_НомерЭлементаВмассивеТекущегоУровня
  236. for i = 1:length(levelOneArrayExpression)
  237. levelString = "l_1_$(i)"
  238. str = replace(str, levelOneArrayExpression[i] => levelString)
  239. end
  240.  
  241. #первый уровень в allLevelsBracket всегда пустой
  242. levelOneArrayBracket = Bracket[]
  243. push!(allLevelsBracket, levelOneArrayBracket)
  244.  
  245. println(str);
  246.  
  247. return str
  248. end
  249.  
  250. # Для всех уровней кроме 1
  251. function otherLevels(str, levelNumber)
  252.  
  253. # строка всегда начинается со скобки, кроме самого последнего уровня
  254. # если строка начинается не со скобки, значит это последний уровень и функция завершает свою работу
  255. if SubString(str, 1, 1) != openBranch
  256. thisLevelArrayExpression = String[]
  257. push!(thisLevelArrayExpression, str)
  258. push!(allLevelsExpression, thisLevelArrayExpression)
  259. return
  260. end
  261.  
  262. thisLevelArrayExpression = String[]
  263. thisLevelArrayBracket = Bracket[]
  264.  
  265. indexStart = 1
  266. haveBranch = false
  267.  
  268. for i = 1:length(str)
  269. symbol = SubString(str, i, i)
  270.  
  271. if symbol == openBranch
  272. indexStart = i
  273. haveBranch = true
  274. elseif symbol == closeBranch && haveBranch
  275. symbolsInBrances = SubString(str, indexStart, i)
  276. if !checkSymbolInArray(thisLevelArrayExpression, symbolsInBrances)
  277. push!(thisLevelArrayExpression, string(symbolsInBrances))
  278. end
  279. haveBranch = false
  280. end
  281.  
  282. end
  283.  
  284. # добавляем массив выражений данного "уровня" в массив "уровней"
  285. push!(allLevelsExpression, thisLevelArrayExpression)
  286.  
  287. # создает "bracket-ы" и добавляет их в массив
  288. for i = 1:length(thisLevelArrayExpression)
  289. bracket = bracketParse(thisLevelArrayExpression[i])
  290. if !checkBracketInArray(thisLevelArrayBracket, bracket)
  291. push!(thisLevelArrayBracket, bracket)
  292. end
  293. end
  294.  
  295. # добавляем массив "bracket-ов" данного "уровня" в массив "уровней"
  296. push!(allLevelsBracket, thisLevelArrayBracket)
  297.  
  298.  
  299. # заменяем все элементы строки на l_НомерУровня_НомерЭлементаВмассивеТекущегоУровня
  300. for i = 1:length(thisLevelArrayExpression)
  301. levelNumber = levelNumber #для того, что в цикле был доступ к levelNubmber
  302. levelString = "l_$(levelNumber)_$(i)"
  303. str = replace(str, thisLevelArrayExpression[i] => levelString)
  304. end
  305. println(str);
  306.  
  307. # вызываем функцию для новой строки и следующего уровня
  308. otherLevels(str, levelNumber + 1)
  309. end
  310.  
  311. inputStr = level1(inputStr)
  312. otherLevels(inputStr, 2)
  313.  
  314. println()
  315. allLevelsExpressionPrint()
  316. println()
  317. allLevelsBracketPrint()
  318.  
  319. # Рисует круг в точке (x, y) с текстом "text" внутри
  320. function drawCircleWithText(scene, x, y, text)
  321.  
  322. radius = convert(Float32, RADIUS)
  323.  
  324. points = decompose(Point2f0, Circle(Point2f0(x, y), radius))
  325. poly!(scene, points, color = :white, strokewidth = 2, strokecolor = :black)
  326.  
  327. text!(scene, text, textsize = 20, position = (x, y), align = (:center, :center))
  328. end
  329.  
  330. # Рисует линию из точки (x1, y1) в точку (x2, y2)
  331. function drawLine(scene, x1, y1, x2, y2)
  332. linesegments!(scene, [Point(x1,y1)=> Point(x2,y2)] )
  333. end
  334.  
  335.  
  336. # Высчитывает вершины графа
  337. function calculatedGraph(bracket, xLeft, xRight, currentLevel)
  338. # индекс вершины
  339. global graphIndex = graphIndex + 1
  340. thisIndex = graphIndex
  341.  
  342. countLevels = length(allLevelsBracket)
  343.  
  344. x = (xLeft + xRight) / 2
  345. y = VISOTA / (countLevels + 1) * currentLevel
  346.  
  347. # индексы "детей" вершины
  348. indexLeft = 0
  349. indexRight = 0
  350.  
  351. if bracket.sign != ""
  352.  
  353. text = bracket.sign
  354.  
  355. # если есть "левая ветка"
  356. if bracket.arg1 != ""
  357. level1 = levelNameParse(bracket.arg1)[1]
  358. index1 = levelNameParse(bracket.arg1)[2]
  359.  
  360. # println("Left from $bracket")
  361. # для первого уровня нету Bracket, поэтому мы создаем Bracket в котором sign = "", arg1 = "", arg2 = "Буква_которую надо написать"
  362. if level1 == 1
  363. indexLeft = calculatedGraph(Bracket("", "", allLevelsExpression[level1][index1]), xLeft, xLeft + (xRight - xLeft) / 2, currentLevel - 1)
  364. else
  365. indexLeft = calculatedGraph(allLevelsBracket[level1][index1], xLeft, xLeft + (xRight - xLeft) / 2, currentLevel - 1)
  366. end
  367.  
  368. end
  369.  
  370. level2 = levelNameParse(bracket.arg2)[1]
  371. index2 = levelNameParse(bracket.arg2)[2]
  372.  
  373. # для первого уровня нету Bracket, поэтому мы создаем Bracket в котором sign = "", arg1 = "", arg2 = "Буква_которую надо написать"
  374. if level2 == 1
  375. if bracket.arg1 != ""
  376. indexRight = calculatedGraph(Bracket("", "", allLevelsExpression[level2][index2]), xLeft + (xRight - xLeft) / 2, xRight, currentLevel - 1)
  377. else
  378. indexRight = calculatedGraph(Bracket("", "", allLevelsExpression[level2][index2]), xLeft, xRight, currentLevel - 1)
  379. end
  380. else
  381. if bracket.arg1 != ""
  382. indexRight = calculatedGraph(allLevelsBracket[level2][index2], xLeft + (xRight - xLeft) / 2, xRight, currentLevel - 1)
  383. else
  384. indexRight = calculatedGraph(allLevelsBracket[level2][index2], xLeft, xRight, currentLevel - 1)
  385. end
  386. end
  387. else
  388. text = bracket.arg2
  389. end
  390.  
  391. push!(allVertex, VertexGraph(thisIndex, x, y, text, indexLeft, indexRight))
  392.  
  393. return thisIndex
  394. end
  395.  
  396. # Рисует все вершины
  397. function drawCircles(scene)
  398. for i = 1:length(curentVertex)
  399. v = curentVertex[i]
  400. drawCircleWithText(scene, v.x, v.y, v.text)
  401. end
  402. end
  403.  
  404. # Очищает сцену
  405. function clearScene(scene)
  406. arr = Point{2,Float32}[]
  407. xLeft = 0
  408. xRight = 500
  409. yTop = 500
  410. yBot = 0
  411. mas = []
  412. push!(arr, Point2f0(xLeft, yBot))
  413. push!(arr, Point2f0(xLeft, yTop))
  414. push!(arr, Point2f0(xRight, yTop))
  415. push!(arr, Point2f0(xRight, yBot))
  416. push!(arr, Point2f0(xLeft, yBot))
  417. poly!(scene, arr, color = :white, strokewidth = 10000, strokecolor = :white)
  418. end
  419.  
  420. # Рисует ребра графа от заданной вершины, а так же все ребра "детей" этой вершины
  421. function drawEdges(scene, index)
  422. # index = -1 если такой вершины нету
  423. if index != -1
  424. v1 = curentVertex[index]
  425. x1 = v1.x
  426. y1 = v1.y - RADIUS
  427.  
  428. if v1.left != 0
  429. leftIndex = getNumberVertexInCurentVertexByIndex(v1.left)
  430. v2 = curentVertex[leftIndex]
  431. x2 = v2.x
  432. y2 = v2.y + RADIUS
  433. drawLine(scene, x1, y1, x2, y2)
  434. drawEdges(scene, leftIndex)
  435. end
  436.  
  437. if v1.right != 0
  438. rightIndex = getNumberVertexInCurentVertexByIndex(v1.right)
  439. v2 = curentVertex[rightIndex]
  440. x2 = v2.x
  441. y2 = v2.y + RADIUS
  442. drawLine(scene, x1, y1, x2, y2)
  443. drawEdges(scene, rightIndex)
  444. end
  445.  
  446. end
  447. end
  448.  
  449. # Проверяет, лежит ли точка (x, y) внутри какой-либо вершины из массива curentVertex
  450. # Если не лежит, возвращает -1
  451. function checkPointInVertices(x, y)
  452. for i = 1:length(curentVertex)
  453. v = curentVertex[i]
  454. if checkVertexInCircle(x, y, v.x, v.y)
  455. println("Эта точка лежит в вершине $(v.index)")
  456. return v.index
  457. end
  458. end
  459. println("Эта точка не лежит ни в одной вершине")
  460. return -1
  461. end
  462.  
  463. # Развертывание графа
  464. function reamer(scene, numberVertex)
  465. v = curentVertex[getNumberVertexInCurentVertexByIndex(numberVertex)]
  466. left, right = checkChildrenInAllVertex(numberVertex)
  467. if left != 0 || right != 0
  468. if left != 0
  469. vLeft = allVertex[getNumberVertexInAllVertexByIndex(left)]
  470. # добавляем копии атрибутов, чтобы не было ссылки на элемент из allVertex
  471. # добавляем left = 0, right = 0, т.к. не известно, есть ли у них свои дети и надо это проверить
  472. push!(curentVertex, VertexGraph(vLeft.index, vLeft.x, vLeft.y, vLeft.text, 0, 0))
  473. # обозначаем левого ребенка
  474. v.left = left
  475. # запускаем проверку детей у левого ребенка
  476. reamer(scene, left)
  477. end
  478. if right != 0
  479. vRight = allVertex[getNumberVertexInAllVertexByIndex(right)]
  480. # добавляем копии атрибутов, чтобы не было ссылки на элемент из allVertex
  481. # добавляем left = 0, right = 0, т.к. не известно, есть ли у них свои дети и надо это проверить
  482. push!(curentVertex, VertexGraph(vRight.index, vRight.x, vRight.y, vRight.text, 0, 0))
  483. # обозначаем правого ребенка
  484. v.right = right
  485. # запускаем проверку детей у правого ребенка
  486. reamer(scene, right)
  487. end
  488. end
  489. end
  490.  
  491. # Свертка графа
  492. function convolution(scene, numberVertex)
  493. v = curentVertex[getNumberVertexInCurentVertexByIndex(numberVertex)]
  494. # leftFormula = ""
  495. # rightFormula = ""
  496. # Если есть левый ребенок
  497. if v.left != 0
  498. # Запускаем проверку детей у левого ребенка
  499. convolution(scene, v.left)
  500. # Удаляем левого ребенка
  501. deleteFromCurentVertexByIndex(v.left)
  502. # Показываем, что левого ребенка нет
  503. v.left = 0
  504. end
  505. if v.right != 0
  506. # Запускаем проверку детей у правого ребенка
  507. convolution(scene, v.right)
  508. # Удаляем правого ребенка
  509. deleteFromCurentVertexByIndex(v.right)
  510. # Показываем, что левого правого нет
  511. v.right = 0
  512. end
  513. # return leftFormula * v.text * rightFormula
  514. end
  515.  
  516. # Интерактивность
  517. function interactivity(scene, numberVertex)
  518. v = curentVertex[getNumberVertexInCurentVertexByIndex(numberVertex)]
  519.  
  520. # Разворачивание
  521. # Если детей нет
  522. if v.left == 0 & v.right == 0
  523. left, right = checkChildrenInAllVertex(numberVertex)
  524. if left != 0 || right != 0
  525. reamer(scene, numberVertex)
  526. drawGraph(scene)
  527. end
  528. # Сворачивание
  529. # Если есть дети
  530. elseif v.left != 0 || v.right != 0
  531. convolution(scene, numberVertex)
  532. drawGraph(scene)
  533. end
  534.  
  535. end
  536.  
  537. # Рисует граф
  538. function drawGraph(scene)
  539. println()
  540. curentVertexPrint()
  541.  
  542. clearScene(scene)
  543. drawCircles(scene)
  544. drawEdges(scene, getNumberVertexInCurentVertexByIndex(1))
  545. end
  546.  
  547.  
  548. graphIndex = 0
  549.  
  550. calculatedGraph(allLevelsBracket[length(allLevelsBracket)][1],
  551. 0, SHIRINA, length(allLevelsBracket));
  552.  
  553. println()
  554. allVertexPrint()
  555.  
  556. scene = Scene(resolution = (SHIRINA, VISOTA))
  557. # Добавляем события на кнопки мыши
  558. on(scene.events.mousebuttons) do buttons
  559. if ispressed(scene, Mouse.left)
  560. pos = to_world(scene, Point2f0(scene.events.mouseposition[]))
  561. println("Кликнули сюда $pos")
  562.  
  563. numberVertex = checkPointInVertices(pos[1], pos[2])
  564. if numberVertex != -1
  565. interactivity(scene, numberVertex)
  566. end
  567. end
  568. return
  569. end
  570.  
  571. # Инициализируем массив текущих вершин
  572. for i = 1:length(allVertex)
  573. # Создаем копии объектов, чтобы не было ссылок
  574. v = allVertex[i]
  575. push!(curentVertex, VertexGraph(v.index, v.x, v.y, v.text, v.left, v.right))
  576. end
  577. # curentVertex = allVertex
  578. drawGraph(scene)
  579.  
  580.  
  581. # Без этого не рисуется ????????????????????????
  582. clicks = Node(Point2f0[(0,0)])
  583. scatter!(scene, clicks, color = :red, marker = '+', markersize = 0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement