Advertisement
czaffik

Graph

May 5th, 2019 (edited)
2,982
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
QML 13.61 KB | None | 0 0
  1. // main.qml:
  2. import QtQuick 2.9
  3. import QtQuick.Window 2.2
  4. import QtQuick.Controls 2.4
  5.  
  6. Window {
  7.     visible: true
  8.     width: 640
  9.     height: 640
  10.     title: qsTr("graph")
  11.  
  12.     Graph {
  13.         id: graph
  14.         x: 8
  15.         y: 8
  16.         width: 621
  17.         height: 397
  18.     }
  19.  
  20.     Button {
  21.         id: button
  22.         x: 165
  23.         y: 418
  24.         width: 150
  25.         height: 40
  26.         text: qsTr("wyczyść")
  27.  
  28.         onClicked: clear()
  29.     }
  30.  
  31.     Button {
  32.         id: button1
  33.         x: 8
  34.         y: 418
  35.         width: 150
  36.         text: qsTr("wynik")
  37.  
  38.         onClicked: result()
  39.     }
  40.  
  41.     ScrollView {
  42.         id: scrollView
  43.         x: 8
  44.         y: 503
  45.         width: 178
  46.         height: 125
  47.  
  48.         Text {
  49.             id: text1
  50.             anchors.fill: parent
  51.             font.pixelSize: 12
  52.         }
  53.     }
  54.  
  55.     TextInput {
  56.         id: textInput
  57.         x: 283
  58.         y: 495
  59.         width: 53
  60.         height: 16
  61.         text: "0"
  62.         selectionColor: "#008069"
  63.         font.pixelSize: 12
  64.     }
  65.  
  66.     TextInput {
  67.         id: textInput1
  68.         x: 398
  69.         y: 495
  70.         width: 53
  71.         height: 16
  72.         text: "0"
  73.         font.pixelSize: 12
  74.     }
  75.  
  76.     Label {
  77.         id: label
  78.         x: 8
  79.         y: 469
  80.         width: 166
  81.         height: 20
  82.         text: qsTr("Lista sąsiedztwa:")
  83.         verticalAlignment: Text.AlignVCenter
  84.         horizontalAlignment: Text.AlignLeft
  85.     }
  86.  
  87.     Label {
  88.         id: label1
  89.         x: 238
  90.         y: 469
  91.         width: 213
  92.         height: 20
  93.         text: qsTr("Przeszukiwanie:")
  94.         verticalAlignment: Text.AlignVCenter
  95.         horizontalAlignment: Text.AlignLeft
  96.     }
  97.  
  98.     ScrollView {
  99.         id: scrollView1
  100.         x: 238
  101.         y: 523
  102.         width: 391
  103.         height: 105
  104.  
  105.         Text {
  106.             id: text4
  107.             anchors.fill: parent
  108.             font.pixelSize: 12
  109.         }
  110.     }
  111.  
  112.     Label {
  113.         id: label2
  114.         x: 238
  115.         y: 495
  116.         width: 34
  117.         height: 15
  118.         text: qsTr("start:")
  119.         verticalAlignment: Text.AlignTop
  120.         horizontalAlignment: Text.AlignLeft
  121.     }
  122.  
  123.     Label {
  124.         id: label3
  125.         x: 342
  126.         y: 495
  127.         width: 43
  128.         height: 15
  129.         text: qsTr("koniec:")
  130.         horizontalAlignment: Text.AlignLeft
  131.     }
  132.  
  133.     Button {
  134.         id: button3
  135.         x: 321
  136.         y: 418
  137.         width: 150
  138.         text: qsTr("graf skierowany")
  139.  
  140.         onClicked: changeGraphType()
  141.     }
  142.  
  143.     Grid {
  144.         id: grid
  145.         x: 8
  146.         y: 5
  147.         width: 621
  148.         height: 629
  149.     }
  150.  
  151.     function clear() {
  152.         graph.clear();
  153.         text1.text = '';
  154.         text4.text = '';
  155.     }
  156.  
  157.     function result() {
  158.         if (graph.vertex.length === 0) return;
  159.  
  160.         var text = '';
  161.  
  162.         for (var i = 0; i < graph.al.length; i++) {
  163.             text += i + ': ';
  164.             for (var j = 0; j < graph.al[i].length; j++) {
  165.                 text +=  graph.al[i][j] + ' ';
  166.             }
  167.             text += '\n';
  168.         }
  169.  
  170.         text1.text = text;
  171.  
  172.  
  173.         var start = parseInt(textInput.text);
  174.         var text2 = '';
  175.  
  176.         text2 += 'BFS: ';
  177.         text2 += graph.bfs(start) + '\n\n';
  178.  
  179.         text2 += 'DFS: ';
  180.         text2 += graph.dfs(start) + '\n\n';
  181.  
  182.         text2 += 'Najkrótsza ścieżka: ';
  183.         text2 += graph.pathBFS(parseInt(textInput.text), parseInt(textInput1.text));
  184.         text2 += '\n';
  185.  
  186.         text2 += 'Ścieżka: ';
  187.         text2 += graph.pathDFS(parseInt(textInput.text), parseInt(textInput1.text));
  188.  
  189.         text4.text = text2;
  190.     }
  191.  
  192.     function changeGraphType() {
  193.         if (button3.text === 'graf skierowany') {
  194.             button3.text = 'graf nieskierowany';
  195.             graph.setDirected(false);
  196.         }
  197.         else {
  198.             button3.text = 'graf skierowany';
  199.             graph.setDirected(true);
  200.         }
  201.     }
  202. }
  203.  
  204. // Graph.qml:
  205. import QtQuick 2.0
  206.  
  207. Item {
  208.     id: graph
  209.  
  210.     Rectangle {
  211.         id: area
  212.         anchors.fill: parent
  213.         color: "#cfdfef"
  214.     }
  215.  
  216.     property variant vertex: [];
  217.     property variant edge: [];
  218.     property variant al: [];
  219.     property int size: 0;
  220.     property int numVertex: 0;
  221.     property int prevEdge: -1;
  222.     property int lastEdge: -1;
  223.     property bool directed: true;
  224.  
  225.     MouseArea {
  226.         id: graphMouseArea
  227.         anchors.fill: parent
  228.         onClicked: {
  229.             if (!selectVertex(mouseX, mouseY)) addVertex(mouseX, mouseY);
  230.         }
  231.     }
  232.  
  233.     function selectVertex(x, y) {
  234.         for (var i = 0; i < vertex.length; i++) {
  235.             if ((x >= vertex[i].x && x <= vertex[i].x + vertex[i].width) &&
  236.                 (y >= vertex[i].y && y <= vertex[i].y + vertex[i].height))
  237.             {
  238.                 if (!vertex[i].selected) {
  239.                     vertex[i].select();
  240.                     if (prevEdge === -1) {
  241.                         prevEdge = i;
  242.                         return true;
  243.                     }
  244.                     else {
  245.                         lastEdge = i;
  246.                         addEdge(prevEdge, lastEdge);
  247.                         vertex[lastEdge].unselect();
  248.                         vertex[prevEdge].unselect();
  249.                         prevEdge = -1;
  250.                         lastEdge = -1;
  251.                         return true;
  252.                     }
  253.                 }
  254.                 else {
  255.                     vertex[i].unselect();
  256.                     prevEdge = -1;
  257.                     return true;
  258.                 }
  259.             }
  260.         }
  261.  
  262.         if (prevEdge !== -1) return true;
  263.         return false;
  264.     }
  265.  
  266.     function addVertex(x, y) {
  267.         x -= 15;
  268.         y -= 15;
  269.         vertex.push(Qt.createQmlObject('Vertex {x: ' + x + '; y: ' + y + '; number: ' + numVertex + '}', graph));
  270.         al.push([]);
  271.         numVertex += 1;
  272.     }
  273.  
  274.     function addEdge(i, j) {
  275.         if (edgeExist(i, j)) return;
  276.  
  277.         var x1 = vertex[i].x + vertex[i].width/2;
  278.         var y1 = vertex[i].y + vertex[i].height/2;
  279.  
  280.         var x2 = vertex[j].x + vertex[j].width/2;
  281.         var y2 = vertex[j].y + vertex[j].height/2;
  282.  
  283.         var x = x2-x1;
  284.         var y = y2-y1;
  285.  
  286.         var angle = Math.atan(Math.abs(y)/Math.abs(x));
  287.         if (x < 0 && y >= 0) angle = Math.PI - angle;
  288.         else if (x < 0 && y < 0) angle = Math.PI + angle;
  289.         else if (x >= 0 && y < 0) angle = 2.0*Math.PI - angle;
  290.  
  291.         if (directed) {
  292.             edge.push(Qt.createQmlObject('Edge {sx: ' + x1 + '; sy: ' + y1 + '; ex: ' + x2 + '; ey: ' + y2 + '; angle: ' + angle + '}', graph));
  293.             al[i].unshift(j);
  294.         }
  295.         else {
  296.             edge.push(Qt.createQmlObject('UEdge {sx: ' + x1 + '; sy: ' + y1 + '; ex: ' + x2 + '; ey: ' + y2 + '; angle: ' + angle + '}', graph));
  297.             al[i].unshift(j);
  298.             al[j].unshift(i);
  299.         }
  300.     }
  301.  
  302.     function edgeExist(i, j) {
  303.         for (var l = 0; l < al[i].length; l++) {
  304.             if (al[i][l] === j) return true;
  305.         }
  306.  
  307.         return false;
  308.     }
  309.  
  310.     function clear() {
  311.         for (var i = 0; i < vertex.length; i++) vertex[i].destroy();
  312.         for (var i = 0; i < edge.length; i++) edge[i].destroy();
  313.         vertex = [];
  314.         edge = [];
  315.         al = [];
  316.         size = 0;
  317.         numVertex = 0;
  318.         prevEdge = -1;
  319.         lastEdge = -1;
  320.     }
  321.  
  322.     function bfs(start) {
  323.         var text = '';
  324.         var visited = [];
  325.         for (var i = 0; i < al.length; i++) visited.push(false);
  326.         visited[start] = true;
  327.  
  328.         var queue = [];
  329.         queue.push(start);
  330.  
  331.         while (queue.length !== 0) {
  332.             var p = queue.shift();
  333.             text += p + ' ';
  334.  
  335.             for (var i = 0; i < al[p].length; i++) {
  336.                 if (!visited[al[p][i]]) {
  337.                     visited[al[p][i]] = true;
  338.                     queue.push(al[p][i]);
  339.                 }
  340.             }
  341.         }
  342.  
  343.         return text;
  344.     }
  345.  
  346.     function dfs(start) {
  347.         var text = '';
  348.         var visited = [];
  349.         for (var i = 0; i < al.length; i++) visited.push(false);
  350.         visited[start] = true;
  351.  
  352.         var stack = [];
  353.         stack.push(start);
  354.  
  355.         while (stack.length !== 0) {
  356.             var p = stack.pop();
  357.             text += p + ' ';
  358.  
  359.             for (var i = 0; i < al[p].length; i++) {
  360.                 if (!visited[al[p][i]]) {
  361.                     visited[al[p][i]] = true;
  362.                     stack.push(al[p][i]);
  363.                 }
  364.             }
  365.         }
  366.  
  367.         return text;
  368.     }
  369.  
  370.     function pathBFS(start, end) {
  371.         var text = '';
  372.         var visited = [];
  373.         var p = [];
  374.         var found = false;
  375.  
  376.         for (var i = 0; i < al.length; i++) visited.push(false);
  377.         visited[start] = true;
  378.         p[start] = -1;
  379.  
  380.         var queue = [];
  381.         queue.push(start);
  382.  
  383.         while (queue.length !== 0) {
  384.             var v = queue.shift();
  385.  
  386.             if (v === end) {
  387.                 found = true;
  388.                 break;
  389.             }
  390.  
  391.             for (var i = 0; i < al[v].length; i++) {
  392.                 if (!visited[al[v][i]]) {
  393.                     p[al[v][i]] = v;
  394.                     visited[al[v][i]] = true;
  395.                     queue.push(al[v][i]);
  396.                 }
  397.             }
  398.         }
  399.  
  400.         var t = [];
  401.         if (!found) text = "Nie ma połączenia między punktami: " + start + " " + end;
  402.         else {
  403.             while (v > -1) {
  404.                 t.push(v);
  405.                 v = p[v];
  406.             }
  407.         }
  408.  
  409.         t.reverse();
  410.  
  411.         for (var i = 0; i < t.length; i++) text += t[i] + ' ';
  412.  
  413.         return text;
  414.     }
  415.  
  416.     function pathDFS(start, end) {
  417.         var text = '';
  418.         var visited = [];
  419.         var p = [];
  420.         var found = false;
  421.  
  422.         for (var i = 0; i < al.length; i++) visited.push(false);
  423.         visited[start] = true;
  424.         p[start] = -1;
  425.  
  426.         var stack = [];
  427.         stack.push(start);
  428.  
  429.         while (stack.length !== 0) {
  430.             var v = stack.pop();
  431.  
  432.             if (v === end) {
  433.                 found = true;
  434.                 break;
  435.             }
  436.  
  437.             for (var i = 0; i < al[v].length; i++) {
  438.                 if (!visited[al[v][i]]) {
  439.                     p[al[v][i]] = v;
  440.                     visited[al[v][i]] = true;
  441.                     stack.push(al[v][i]);
  442.                 }
  443.             }
  444.         }
  445.  
  446.         var t = [];
  447.         if (!found) text = "Nie ma połączenia między punktami: " + start + " " + end;
  448.         else {
  449.             while (v > -1) {
  450.                 t.push(v);
  451.                 v = p[v];
  452.             }
  453.         }
  454.  
  455.         t.reverse();
  456.  
  457.         for (var i = 0; i < t.length; i++) text += t[i] + ' ';
  458.  
  459.         return text;
  460.     }
  461.  
  462.     function setDirected(dir) {
  463.         directed = dir;
  464.         for (var i = 0; i < edge.length; i++) edge[i].destroy();
  465.         edge = [];
  466.         var cal = [];
  467.  
  468.         for (var i = 0; i < al.length; i++) {
  469.             cal[i] = [];
  470.             for (var j = 0; j < al[i].length; j++) {
  471.                 cal[i][j] = al[i][j];
  472.             }
  473.         }
  474.  
  475.         al = [];
  476.         for (var k = 0; k < cal.length; k++) {
  477.             al.push([]);
  478.         }
  479.  
  480.         for (var l = 0; l < cal.length; l++) {
  481.             for (var m = 0; m < cal[l].length; m++) {
  482.                 addEdge(l, cal[l][m]);
  483.             }
  484.         }
  485.     }
  486. }
  487.  
  488. // Vertex.qml:
  489. import QtQuick 2.0
  490.  
  491. Rectangle {
  492.     id: root
  493.     property int number
  494.     property color borderColor: "black"
  495.     property bool selected: false
  496.     signal activated()
  497.     signal unactivated()
  498.  
  499.     width: 30;
  500.     height: 30;
  501.     border.width: 4;
  502.     border.color: borderColor;
  503.     color: "transparent";
  504.     radius: width*0.5;
  505.  
  506.     Text {
  507.         color: "red"
  508.         x: root.width/2 - width/2
  509.         y: root.height/2 - height/2
  510.         text: number
  511.     }
  512.  
  513.     function select() {
  514.         selected = true;
  515.         borderColor = "red";
  516.     }
  517.  
  518.     function unselect() {
  519.         selected = false;
  520.         borderColor = "black";
  521.     }
  522. }
  523.  
  524. // Edge.qml:
  525. import QtQuick 2.0
  526. import QtQuick.Shapes 1.11
  527.  
  528. Shape {
  529.     id:root
  530.     property int sx: 0
  531.     property int sy: 0
  532.     property int ex: 0
  533.     property int ey: 0
  534.     property real angle: 0.0
  535.     property real a: 0.0
  536.     property bool directed: true
  537.  
  538.     ShapePath {
  539.         strokeColor: "black"
  540.         strokeWidth: 2
  541.         startX: sx; startY: sy;
  542.         PathLine { x: ex; y: ey }
  543.     }
  544.  
  545.     ShapePath {
  546.         strokeColor: "black"
  547.         strokeWidth: 2
  548.         startX: ex; startY: ey;
  549.         PathLine {
  550.             x: ex - 10*Math.cos(a+angle)
  551.             y: ey - 10*Math.sin(a+angle)
  552.         }
  553.     }
  554.  
  555.     ShapePath {
  556.         strokeColor: "black"
  557.         strokeWidth: 2
  558.         startX: ex; startY: ey;
  559.         PathLine {
  560.             x: ex - 10*Math.cos(a-angle)
  561.             y: ey + 10*Math.sin(a-angle)
  562.         }
  563.     }
  564.  
  565.     Component.onCompleted: {
  566.         a = (Math.PI*30.0)/180.0;
  567.  
  568.         sx += 15*Math.cos(angle);
  569.         sy += 15*Math.sin(angle);
  570.  
  571.         ex -= 15*Math.cos(angle);
  572.         ey -= 15*Math.sin(angle);
  573.     }
  574. }
  575.  
  576. // UEdge.qml:
  577. import QtQuick 2.0
  578. import QtQuick.Shapes 1.11
  579.  
  580. Shape {
  581.     id:root
  582.     property int sx: 0
  583.     property int sy: 0
  584.     property int ex: 0
  585.     property int ey: 0
  586.     property real angle: 0.0
  587.  
  588.     ShapePath {
  589.         strokeColor: "black"
  590.         strokeWidth: 2
  591.         startX: sx; startY: sy;
  592.         PathLine { x: ex; y: ey }
  593.     }
  594.  
  595.     Component.onCompleted: {
  596.         sx += 15*Math.cos(angle);
  597.         sy += 15*Math.sin(angle);
  598.  
  599.         ex -= 15*Math.cos(angle);
  600.         ey -= 15*Math.sin(angle);
  601.     }
  602. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement