OverviewFilesCommitsIssuesDocsReleasesPeers

Attila772-hypergodot commits / 071f8f1

Initial commit
071f8f1c002d656432481662b2c72d8b489cdbfb
by Attila772 <71554727+Attila772@users.noreply.github.com> · 2024-02-20T10:54:19.000Z

Changed files (13) +505 -0

.gitattributes +2 -0
……@@ -0,0 +1,2 @@
1# Normalize EOL for all files that Git considers text files.
2* text=auto eol=lf
.gitignore +2 -0
……@@ -0,0 +1,2 @@
1# Godot 4+ specific ignores
2.godot/
HyperEdge.gd +86 -0
……@@ -0,0 +1,86 @@
1extends Node2D
2
3var nodes: Dictionary
4var color: Color
5var width = 5
6var dragging = false
7func _ready():
8 pass
9func _process(delta):
10 if dragging:
11 queue_redraw()
12
13func _input(event):
14 if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
15 if event.pressed:
16 dragging = true # Start dragging
17 else:
18 dragging = false # Stop dragging
19 queue_redraw() # Optionally, queue a redraw when you stop dragging
20
21
22func _draw():
23 var points = []
24 for node_id in nodes:
25 var node = get_node_from_group(node_id)
26 if node:
27 var center = node.position
28 var radius = nodes[node_id]
29 points += generate_circle_points(center, radius, 20) # 8 points per circle for approximation
30 #for point in points:
31 # draw_circle(point, 2, Color(1, 0, 0, 1)) # Draw each point as a small circle
32
33
34 var hull = gift_wrapping(points)
35 #for point in hull:
36 # draw_circle(point, 2, Color(1, 0, 0, 1)) # Draw each point as a small circle
37 if hull.size() > 0 and hull[0] != hull[hull.size() - 1]:
38 hull.append(hull[0])
39 for i in range(hull.size() - 1):
40 draw_line(hull[i], hull[i + 1], color, width) # Change '2' to your desired width
41
42var p0
43
44func generate_circle_points(center, radius, point_count):
45 var points = []
46 for i in range(point_count):
47 var angle = 2 * PI * i / point_count
48 points.append(center + Vector2(cos(angle), sin(angle)) * radius)
49 return points
50
51func orientation(p, q, r):
52 var val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y)
53 return 0 if val == 0 else (1 if val > 0 else 2)
54
55func gift_wrapping(points):
56 if points.size() < 3:
57 return []
58 var hull = []
59 var l = 0
60 for i in range(1, points.size()):
61 if points[i].x < points[l].x:
62 l = i
63 var p = l
64 var q
65 while true:
66
67 q = (p + 1) % points.size()
68 for r in range(points.size()):
69 if orientation(points[p], points[q], points[r]) == 2:
70 q = r
71 elif orientation(points[p], points[q], points[r]) == 0:
72 if points[p].distance_to(points[r]) > points[p].distance_to(points[q]):
73 q = r
74 hull.append(points[p])
75 p = q
76 if p == l:
77 break
78 return hull
79
80
81func get_node_from_group(node_id) -> Node2D:
82 var nodes_group = get_tree().get_nodes_in_group("nodes")
83 for node in nodes_group:
84 if str(node.name) == str(node_id):
85 return node
86 return null
HyperEdge.tscn +6 -0
……@@ -0,0 +1,6 @@
1[gd_scene load_steps=2 format=3 uid="uid://nx4jmlyy1jhv"]
2
3[ext_resource type="Script" path="res://HyperEdge.gd" id="1_rm3x8"]
4
5[node name="HyperEdge" type="Node2D"]
6script = ExtResource("1_rm3x8")
HyperNode.gd +73 -0
……@@ -0,0 +1,73 @@
1extends Node2D
2
3var edges = []
4var dragging = false
5var drag_offset = Vector2.ZERO
6var offset_circles = []
7var node_id = "name"
8var circle_usage = {} # Edge instance to circle index
9signal node_drag_started(node)
10signal node_drag_ended(node)
11
12func _set_node_id(value : String):
13 node_id = value
14 var label = get_node("Label")
15 label.text = node_id
16
17func _input(event):
18 if event is InputEventMouseButton:
19 if event.button_index == MOUSE_BUTTON_LEFT:
20 if event.pressed:
21 var mouse_pos = get_viewport().get_mouse_position()
22 if get_rect().has_point(mouse_pos):
23 dragging = true
24 drag_offset = mouse_pos - get_position()
25 emit_signal("node_drag_started", self)
26 modulate = Color(1, 2, 1, 0.7)
27 else:
28 if dragging:
29 emit_signal("node_drag_ended", self)
30 modulate = Color(1, 1, 1, 1)
31 dragging = false
32
33
34func get_rect() -> Rect2:
35 var area = Rect2(-25, -25, 50, 50)
36 area.position.x = position.x + area.position.x
37 area.position.y = position.y + area.position.y
38 return area
39
40func _process(delta):
41 if dragging:
42 var mouse_pos = get_viewport().get_mouse_position()
43 set_position(mouse_pos - drag_offset)
44
45
46func _draw():
47 #randomize() # Initialize the random number generator
48 #for radius in offset_circles:
49 # draw_circle(Vector2(), radius, Color(randf(), randf(), randf(), 0.5)) # Draw semi-transparent circles with random colors
50 pass
51
52# This function should use the edges array, and construct as many circles around the node, with a small offset in the radius, that will be used
53# to connect the edges to the node, and prevent the edges from overlapping the node and other edges
54func make_offset_circles():
55 offset_circles.clear() # Reset previous data
56 var circle_count = edges.size()
57 var base_radius = 25 # Starting radius for the smallest circle
58
59 for i in range(circle_count):
60 var radius = base_radius + i * 5 # Increase radius for each subsequent circle
61 offset_circles.append(radius) # Store only the radius, as center is the node's position
62
63 queue_redraw()
64
65
66
67
68func _ready():
69
70 add_to_group("nodes")
71 make_offset_circles()
72
73 pass
HyperNode.tscn +25 -0
……@@ -0,0 +1,25 @@
1[gd_scene load_steps=3 format=3 uid="uid://dll5p1lerh26o"]
2
3[ext_resource type="Script" path="res://HyperNode.gd" id="1_k5qsc"]
4
5[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_jrb2w"]
6corner_radius_top_left = 30
7corner_radius_top_right = 30
8corner_radius_bottom_right = 30
9corner_radius_bottom_left = 30
10
11[node name="HyperNode" type="Node2D"]
12script = ExtResource("1_k5qsc")
13
14[node name="Panel" type="Panel" parent="."]
15offset_left = -20.0
16offset_top = -20.0
17offset_right = 20.0
18offset_bottom = 20.0
19theme_override_styles/panel = SubResource("StyleBoxFlat_jrb2w")
20
21[node name="Label" type="Label" parent="."]
22offset_left = -20.0
23offset_top = -20.0
24offset_right = 20.0
25offset_bottom = 3.0
export_presets.cfg +65 -0
……@@ -0,0 +1,65 @@
1[preset.0]
2
3name="Windows Desktop"
4platform="Windows Desktop"
5runnable=true
6dedicated_server=false
7custom_features=""
8export_filter="all_resources"
9include_filter=""
10exclude_filter=""
11export_path=""
12encryption_include_filters=""
13encryption_exclude_filters=""
14encrypt_pck=false
15encrypt_directory=false
16script_encryption_key=""
17
18[preset.0.options]
19
20custom_template/debug=""
21custom_template/release=""
22debug/export_console_script=1
23binary_format/embed_pck=false
24texture_format/bptc=true
25texture_format/s3tc=true
26texture_format/etc=false
27texture_format/etc2=false
28binary_format/architecture="x86_64"
29codesign/enable=false
30codesign/identity_type=0
31codesign/identity=""
32codesign/password=""
33codesign/timestamp=true
34codesign/timestamp_server_url=""
35codesign/digest_algorithm=1
36codesign/description=""
37codesign/custom_options=PackedStringArray()
38application/modify_resources=true
39application/icon=""
40application/console_wrapper_icon=""
41application/icon_interpolation=4
42application/file_version=""
43application/product_version=""
44application/company_name=""
45application/product_name=""
46application/file_description=""
47application/copyright=""
48application/trademarks=""
49ssh_remote_deploy/enabled=false
50ssh_remote_deploy/host="user@host_ip"
51ssh_remote_deploy/port="22"
52ssh_remote_deploy/extra_args_ssh=""
53ssh_remote_deploy/extra_args_scp=""
54ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
55$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
56$trigger = New-ScheduledTaskTrigger -Once -At 00:00
57$settings = New-ScheduledTaskSettingsSet
58$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
59Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
60Start-ScheduledTask -TaskName godot_remote_debug
61while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
62Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
63ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
64Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
65Remove-Item -Recurse -Force '{temp_dir}'"
icon.svg +1 -0
……@@ -0,0 +1 @@
1<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><g transform="translate(32 32)"><path d="m-16-32c-8.86 0-16 7.13-16 15.99v95.98c0 8.86 7.13 15.99 16 15.99h96c8.86 0 16-7.13 16-15.99v-95.98c0-8.85-7.14-15.99-16-15.99z" fill="#363d52"/><path d="m-16-32c-8.86 0-16 7.13-16 15.99v95.98c0 8.86 7.13 15.99 16 15.99h96c8.86 0 16-7.13 16-15.99v-95.98c0-8.85-7.14-15.99-16-15.99zm0 4h96c6.64 0 12 5.35 12 11.99v95.98c0 6.64-5.35 11.99-12 11.99h-96c-6.64 0-12-5.35-12-11.99v-95.98c0-6.64 5.36-11.99 12-11.99z" fill-opacity=".4"/></g><g stroke-width="9.92746" transform="matrix(.10073078 0 0 .10073078 12.425923 2.256365)"><path d="m0 0s-.325 1.994-.515 1.976l-36.182-3.491c-2.879-.278-5.115-2.574-5.317-5.459l-.994-14.247-27.992-1.997-1.904 12.912c-.424 2.872-2.932 5.037-5.835 5.037h-38.188c-2.902 0-5.41-2.165-5.834-5.037l-1.905-12.912-27.992 1.997-.994 14.247c-.202 2.886-2.438 5.182-5.317 5.46l-36.2 3.49c-.187.018-.324-1.978-.511-1.978l-.049-7.83 30.658-4.944 1.004-14.374c.203-2.91 2.551-5.263 5.463-5.472l38.551-2.75c.146-.01.29-.016.434-.016 2.897 0 5.401 2.166 5.825 5.038l1.959 13.286h28.005l1.959-13.286c.423-2.871 2.93-5.037 5.831-5.037.142 0 .284.005.423.015l38.556 2.75c2.911.209 5.26 2.562 5.463 5.472l1.003 14.374 30.645 4.966z" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 919.24059 771.67186)"/><path d="m0 0v-47.514-6.035-5.492c.108-.001.216-.005.323-.015l36.196-3.49c1.896-.183 3.382-1.709 3.514-3.609l1.116-15.978 31.574-2.253 2.175 14.747c.282 1.912 1.922 3.329 3.856 3.329h38.188c1.933 0 3.573-1.417 3.855-3.329l2.175-14.747 31.575 2.253 1.115 15.978c.133 1.9 1.618 3.425 3.514 3.609l36.182 3.49c.107.01.214.014.322.015v4.711l.015.005v54.325c5.09692 6.4164715 9.92323 13.494208 13.621 19.449-5.651 9.62-12.575 18.217-19.976 26.182-6.864-3.455-13.531-7.369-19.828-11.534-3.151 3.132-6.7 5.694-10.186 8.372-3.425 2.751-7.285 4.768-10.946 7.118 1.09 8.117 1.629 16.108 1.846 24.448-9.446 4.754-19.519 7.906-29.708 10.17-4.068-6.837-7.788-14.241-11.028-21.479-3.842.642-7.702.88-11.567.926v.006c-.027 0-.052-.006-.075-.006-.024 0-.049.006-.073.006v-.006c-3.872-.046-7.729-.284-11.572-.926-3.238 7.238-6.956 14.642-11.03 21.479-10.184-2.264-20.258-5.416-29.703-10.17.216-8.34.755-16.331 1.848-24.448-3.668-2.35-7.523-4.367-10.949-7.118-3.481-2.678-7.036-5.24-10.188-8.372-6.297 4.165-12.962 8.079-19.828 11.534-7.401-7.965-14.321-16.562-19.974-26.182 4.4426579-6.973692 9.2079702-13.9828876 13.621-19.449z" fill="#478cbf" transform="matrix(4.162611 0 0 -4.162611 104.69892 525.90697)"/><path d="m0 0-1.121-16.063c-.135-1.936-1.675-3.477-3.611-3.616l-38.555-2.751c-.094-.007-.188-.01-.281-.01-1.916 0-3.569 1.406-3.852 3.33l-2.211 14.994h-31.459l-2.211-14.994c-.297-2.018-2.101-3.469-4.133-3.32l-38.555 2.751c-1.936.139-3.476 1.68-3.611 3.616l-1.121 16.063-32.547 3.138c.015-3.498.06-7.33.06-8.093 0-34.374 43.605-50.896 97.781-51.086h.066.067c54.176.19 97.766 16.712 97.766 51.086 0 .777.047 4.593.063 8.093z" fill="#478cbf" transform="matrix(4.162611 0 0 -4.162611 784.07144 817.24284)"/><path d="m0 0c0-12.052-9.765-21.815-21.813-21.815-12.042 0-21.81 9.763-21.81 21.815 0 12.044 9.768 21.802 21.81 21.802 12.048 0 21.813-9.758 21.813-21.802" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 389.21484 625.67104)"/><path d="m0 0c0-7.994-6.479-14.473-14.479-14.473-7.996 0-14.479 6.479-14.479 14.473s6.483 14.479 14.479 14.479c8 0 14.479-6.485 14.479-14.479" fill="#414042" transform="matrix(4.162611 0 0 -4.162611 367.36686 631.05679)"/><path d="m0 0c-3.878 0-7.021 2.858-7.021 6.381v20.081c0 3.52 3.143 6.381 7.021 6.381s7.028-2.861 7.028-6.381v-20.081c0-3.523-3.15-6.381-7.028-6.381" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 511.99336 724.73954)"/><path d="m0 0c0-12.052 9.765-21.815 21.815-21.815 12.041 0 21.808 9.763 21.808 21.815 0 12.044-9.767 21.802-21.808 21.802-12.05 0-21.815-9.758-21.815-21.802" fill="#fff" transform="matrix(4.162611 0 0 -4.162611 634.78706 625.67104)"/><path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042" transform="matrix(4.162611 0 0 -4.162611 656.64056 631.05679)"/></g></svg>
icon.svg.import +37 -0
……@@ -0,0 +1,37 @@
1[remap]
2
3importer="texture"
4type="CompressedTexture2D"
5uid="uid://bq34js3rsxb1o"
6path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7metadata={
8"vram_texture": false
9}
10
11[deps]
12
13source_file="res://icon.svg"
14dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15
16[params]
17
18compress/mode=0
19compress/high_quality=false
20compress/lossy_quality=0.7
21compress/hdr_compression=1
22compress/normal_map=0
23compress/channel_pack=0
24mipmaps/generate=false
25mipmaps/limit=-1
26roughness/mode=0
27roughness/src_normal=""
28process/fix_alpha_border=true
29process/premult_alpha=false
30process/normal_map_invert_y=false
31process/hdr_as_srgb=false
32process/hdr_clamp_exposure=false
33process/size_limit=0
34detect_3d/compress_to=1
35svg/scale=1.0
36editor/scale_with_editor_scale=false
37editor/convert_colors_with_editor_theme=false
main.gd +114 -0
……@@ -0,0 +1,114 @@
1extends Node2D
2
3
4var edges : Dictionary
5var nodes : Dictionary
6class NodeData:
7 var id = 0 # Node identifier
8 var edges = [] # Array to hold edge identifiers (based on line number or custom ID)
9 var support = 0 # Support value
10
11 func _to_string():
12 return "Edges: " + str(edges) + ", Support: " + str(support)
13
14
15
16func create_nodes(nodes: Dictionary):
17 var scene = load("HyperNode.tscn")
18 var row = 1
19 var column = 1
20 var spacing = Vector2(100, 100)
21 var per_row = 10
22 for id in nodes.keys():
23 var node_instance = scene.instantiate()
24 node_instance.node_id = id
25 node_instance.name = str(id)
26 node_instance.position = Vector2(column * spacing.x, row * spacing.y)
27 node_instance._set_node_id(str(id))
28 node_instance.edges = nodes[id].edges
29
30 add_child(node_instance)
31
32 column += 1
33 if column >= per_row:
34 column = 0
35 row += 1
36
37func populate_edge_data():
38 var hyperedge_scene = load("res://HyperEdge.tscn")
39 for node_id in nodes:
40 var node_edges = nodes[node_id].edges
41 var circle_ref = get_node(str(node_id)) # Assuming this gets a node instance with 'offset_circles' available
42 var offset_circles = circle_ref.offset_circles # List of radii for offset circles
43 for edge_index in range(node_edges.size()):
44 var edge_id = node_edges[edge_index]
45 if not edges.has(edge_id):
46 edges[edge_id] = {"nodes": [], "radii": []}
47
48 if edge_index < offset_circles.size(): # Ensure there's a corresponding circle
49 var radius = offset_circles[edge_index]
50 edges[edge_id]["nodes"].append(node_id)
51 edges[edge_id]["radii"].append(radius)
52 else:
53 print("Error: Node %s has more edges (%s) than offset circles provided." % [node_id, node_edges.size()])
54
55 for edge_id in edges:
56 var hyperedge_instance = hyperedge_scene.instantiate()
57 var edge_data = edges[edge_id]
58 var node_radii_pairs = {}
59 for i in range(edge_data["nodes"].size()):
60 var nodeid = edge_data["nodes"][i]
61 var radius = edge_data["radii"][i]
62 node_radii_pairs[nodeid] = radius
63 hyperedge_instance.nodes = node_radii_pairs
64
65 var color = Color(randf(), randf(), randf(), 0.3) # Generate a random color
66 hyperedge_instance.color = color
67 add_child(hyperedge_instance)
68
69
70
71
72
73
74
75func _ready():
76 nodes = read_file("patterns.txt")
77 create_nodes(nodes)
78 populate_edge_data()
79 pass # Replace with function body.
80
81func read_file(path):
82 var file = FileAccess.open(path, FileAccess.READ)
83 var nodes = {} # Dictionary to hold all nodes
84 var edge_id = 0 # Unique identifier for each edge, can use line number as well
85
86 while not file.eof_reached():
87 var line = file.get_line().strip_edges()
88 if line.find("#SUP:") == -1:
89 continue # Skip this line
90 var parts = line.split(" #SUP: ")
91 var node_ids = parts[0].split(" ")
92 var support = int(parts[1])
93
94 # Process each node ID in the line
95 for node_id in node_ids:
96 var id = int(node_id)
97 if not nodes.has(id):
98 nodes[id] = NodeData.new()
99 # Always append the edge_id to the node's edges array
100 nodes[id].edges.append(edge_id)
101 # Update the support value
102 nodes[id].support = max(nodes[id].support, support)
103
104 edge_id += 1 # Increment edge ID for the next line
105
106 file.close()
107 return nodes
108
109
110
111# Called every frame. 'delta' is the elapsed time since the previous frame.
112func _process(delta):
113 pass
114
main.tscn +21 -0
……@@ -0,0 +1,21 @@
1[gd_scene load_steps=2 format=3 uid="uid://2f8fvrck2f38"]
2
3[ext_resource type="Script" path="res://main.gd" id="1_1hwno"]
4
5[node name="Node2D" type="Node2D"]
6script = ExtResource("1_1hwno")
7
8[node name="ColorRect" type="ColorRect" parent="."]
9offset_left = -1010.0
10offset_top = -703.0
11offset_right = 2675.0
12offset_bottom = 1600.0
13color = Color(0.952941, 0.952941, 0.952941, 1)
14
15[node name="CanvasLayer" type="CanvasLayer" parent="."]
16
17[node name="ColorRect" type="ColorRect" parent="CanvasLayer"]
18visible = false
19offset_right = 195.0
20offset_bottom = 401.0
21color = Color(0.0980392, 0.0980392, 0.0980392, 1)
patterns.txt +45 -0
……@@ -0,0 +1,45 @@
1333 335 313 #SUP: 723
2333 335 #SUP: 853
3333 270 #SUP: 1158
4239 #SUP: 1384
5333 239 #SUP: 690
6333 264 293 260 295 325 #SUP: 855
7333 280 315 293 295 325 #SUP: 970
8333 280 293 295 325 #SUP: 1052
9333 264 293 295 325 #SUP: 1151
10333 293 295 325 #SUP: 2091
11333 264 293 260 295 #SUP: 856
12333 280 315 293 295 #SUP: 971
13333 280 293 295 #SUP: 1055
14333 264 293 295 #SUP: 1156
15333 293 295 #SUP: 2103
16333 264 293 260 #SUP: 866
17264 260 #SUP: 2144
18333 264 260 #SUP: 1021
19264 280 266 #SUP: 760
20264 266 #SUP: 2291
21333 264 266 #SUP: 1431
22333 280 315 293 #SUP: 994
23333 280 293 #SUP: 1105
24333 264 293 #SUP: 1209
25333 293 #SUP: 2303
26280 315 282 #SUP: 794
27280 282 #SUP: 953
28333 282 #SUP: 802
29282 #SUP: 2542
30264 280 315 #SUP: 822
31333 264 280 315 #SUP: 729
32333 280 315 #SUP: 2176
33280 315 #SUP: 3522
34290 #SUP: 3635
35264 280 #SUP: 1307
36333 264 280 #SUP: 938
37333 280 #SUP: 2832
38240 280 #SUP: 735
39280 #SUP: 5734
40333 264 #SUP: 2879
41240 264 #SUP: 1397
42264 #SUP: 8897
43333 #SUP: 9224
44240 333 #SUP: 1410
45240 #SUP: 14458
project.godot +28 -0
……@@ -0,0 +1,28 @@
1; Engine configuration file.
2; It's best edited using the editor UI and not directly,
3; since the parameters that go here are not all obvious.
4;
5; Format:
6; [section] ; section goes between []
7; param=value ; assign values to parameters
8
9config_version=5
10
11[application]
12
13config/name="Hypergodot"
14run/main_scene="res://main.tscn"
15config/features=PackedStringArray("4.0", "Forward Plus")
16config/icon="res://icon.svg"
17
18[dotnet]
19
20project/assembly_name="Hypergodot"
21
22[input]
23
24left_click={
25"deadzone": 0.5,
26"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"pressed":false,"double_click":false,"script":null)
27]
28}