Advertisement
czaffik

Graph

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