Specially, the problem i am trying to solve is deleting points that are very close together in a closed polyhedron.
I start first by collecting all the halfedges that are very short in distance (which implies that two points are very close together)
After which i go through the list of halfedges and start deleting the vertices using "erase_center_vertex".
The problem that comes is such that I do not know how to test if a vertex has already been deleted .. so that if some other halfedges references it again and tries to delete it, an error is prompted..
i tried the following....
if ( my_halfedge != Halfedge_handle() ) erase_center_vertex(my_halfedge);
if ( my_halfedge->vertex() != vertex_handle() ) erase_center_vertex(my_halfedge);
In all case, although the vertex is already deleted from the polyhedron, but somehow the halfedge pointing to it still exist, and pointing to a valid vertex (which should have been deleted).
Question : How to test if a vertex or halfedge has been removed?
Related
So basically im doing this for my minecraft spigot plugin (java). I know there are already some land claim plugins but i would like to make my own.
For this claim plugin i'd like to know how to get if a point (minecraft block) is inside a region (rectangle). i know how to check if a point is inside a rectangle, the main problem is how to check as quickly as possible when there are like lets say 10.000 rectangles.
What would be the most efficient way to check 10.000 or even 100.000 without having to manually loop through all of them and check every single rectangle?
Is there a way to add a logical test when the rectangles get generated in a way that checks if they hold that point? In that case you could set a boolean to true if they contain that point when generated, and then when checking for that minecraft block the region (rectangle) replies with true or false.
This way you run the loops or checks when generating the rectangles, but when running the game the replies should happen very fast, just check if true or false for bool ContainsPoint.
If your rectangles are uniformly placed neighbors of each other in a big rectangle, then finding which rectangle contains point is easy:
width = (maxX-minX)/num_rectangles_x;
height = same but for y
idx = floor( (x - minX)/width );
idy = floor( (y - minY)/height );
id_square = idx + idy*num_rectangles_x;
If your rectangles are randomly placed, then you should use a spatial acceleration structure like octree. Then check if point is in root, then check if point is in one of its nodes, repeat until you find a leaf that includes the point. 10000 tests per 10milliseconds should be reachable on cpu. 1 million tests per 10ms should be ok for a gpu. But you may need to implement a sparse version of the octree and a space filling curve order for leaf nodes to have better caching, to reach those performance levels.
I've followed "Procedural Generation in Godot: Dungeon Generation" by KidsCanCode #https://www.youtube.com/watch?v=o3fwlk1NI-w and find myself unable to debug the current problem.
This specific commit has the code, but I'll try to explain in more detail bellow.
My main scene has a Camera2D node, a generic Node2D calles Rooms and a TileMap, everything is empty.
When the script starts, it runs a
func make_room(_pos, _size):
position = _pos
size = _size
var s = RectangleShape2D.new()
s.custom_solver_bias = 0.5
s.extents = size
$CollisionShape2D.shape = s
A few times and it fills $Rooms using .add_child(r) where r is a instance of the node that has the make_room() function. It will then iterate over $Rooms.get_children() a few times to create a AStar node to link all the rooms:
The magic comes when make_map() is called after afterwards, it fills the map with non-walkable blocks and then it carves the empty spaces, which works fine too:
There is a find_start_room() that is called to find the initial room, it also sets a global variable to the Main script start_room, which is used to write 'Start' on the map using draw_string(font, start_room.position - Vector2(125,0),"start",Color(3,4,8))
When I hit 'esc' it runs this simple code to instance the player:
player = Player.instance()
add_child(player)
player.position = start_room.position + Vector2(start_room.size.x/2, start_room.size.y/2)
play_mode = true
The problem comes when spawning the player. I tried doing some 'blind' fixing, such as adding or subtracting a Vector2(start_room.size.x/2, start_room.size.y/2) to player.position to see if I could make it fall within the room, to no avail.
Turning to the debugger didn't help, as the positions expressed by the variable inspectors don't seem to mean anything.
I tried implementing a simple 'mouse click print location':
print("Mouse Click/Unclick at: ", event.position)
print("Node thing",get_node("/root/Main/TileMap").world_to_map(event.position))
And also a 'start_room' print location:
print(get_node("/root/Main/TileMap").world_to_map(start_room.position))
And a when player moves print location, written directly into the Character script:
print(get_node("/root/Main/TileMap").world_to_map(self.position))
Getting results like the ones bellow:
Mouse Click/Unclick at: (518, 293)
Node thing(16, 9)
(-142, 0)
(-147, -3)
So, the player doesn't spawn on the same position as the start_room and the mouse position information is not the same as anything else.
Why is the player now spawning correctly? How can I debug this situation?
EDIT1: User Theraot mentioned about how the RigidBody2D is doing some weird collisions, and from what I understood, changing their collision behavior should fix the whole thing.
There's a section on the code that -after generating the random rooms- it removes some of the rooms like this:
for room in $Rooms.get_children():
if randf() < cull:
room.queue_free()
else:
room.mode = RigidBody2D.MODE_STATIC
room_positions.append(Vector3(room.position.x, room.position.y, 0))
From what I understand, if the room is randomly selected it will be deleted using queue_free() OR it will be appended to a room_positions for further processing. This means if I shift all the rooms to a different collision layer, the player/character instance would be alone with the TileMap on the same collision layer.
So I just added a simple room.collision_layer = 3 changing this section of the code to
for room in $Rooms.get_children():
if randf() < cull:
room.queue_free()
else:
room.mode = RigidBody2D.MODE_STATIC
room.collision_layer = 3
room_positions.append(Vector3(room.position.x, room.position.y, 0))
It doesn't seem to have changed anything, the player still spawns outside the room.
Do you see the rooms spread outwards?
You didn't write code to move the rooms. Sure, the code gives them a random position. But even if you set their position to Vector2.ZERO they move outwards, avoiding overlaps.
Why? Because these rooms are RigidBody2D, and they do push other physics objects. Such as other rooms or the player character.
That's the problem: These rooms are RigidBody2D, and you put your KinematicBody2D player character on top of one of them. The RigidBody2D pushes it out.
The tutorial you followed is exploiting this behavior of RigidBody2Ds to spread the rooms. However you don't need these RigidBody2D after you are done populating your TileMap.
Instead, you can store the start position in a variable for later placing the player character (you don't need offsets - by the way - the position of the room is the center of the room), and then remove the RigidBody2Ds. If you want to keep the code that writes the text, you would also have to modify it, so it does not fail when the room no longer exists.
Alternatively, you can edit their collision layer and mask so they don't collide with the player character (or anything for that matter, but why would you want these RigidBody2Ds that collide with nothing?).
Addendum post edit: Collision layers and mask don't work as you expect.
First of all, the collision layer and mask are flags. The values of the layers are powers of two (1, 2, 4, 8...). So, when you set it to 3, it is the layer 1 plus the layer 2. So it still collides with a collision mask of 1.
And second, even if you changed the collision layer of the rooms to 2 (so it does not match the collision mask of 1 that the player character has). The player character still has a layer 1 which match the collision mask of the rooms.
See also the proposal Make physics layers and masks logic simple and consistent.
Thus, you would need to change the layer and mask. Both. in such way that they don't collide. For example, you can set layer and mask to 0 (which disable all collisions). The algorithm that populates the TileMap does not use the layer and mask.
I am trying to create edges with bends for a layout. Normally, I am using a haystack edge in the graph but whenever an edge bend has to be created, the curve-style of the edge is changed to segments. Currently, I am only creating edges with single bends. I have tried the code provided in this post but it is not creating proper edges. Currently, I am using the code from cytoscape.js-edge-editing, since it is creating better results.
The main problem is that the segment-distances values which cause the bendpoint to be created at the wrong location. Since, the functions in the above provided codes are not creating proper bendpoints, what is the right way to go about this?
A sample problem is as shown:
An edge bend has to created created in the edge from n12 to n15 where n12 is the source. The values of segment-distances and segment-weights are shown in the console. Having a positive value of segment-distances creates the bendpoint at the wrong position. It was actually supposed to be to the right of n12 and to the top of n15.
Whereas in another scenario, as shown in the following figure, an edge bend has to be created in the edge from n3 and n2. And the positions of these nodes are quite similar to n12 and n15 wrt each other. Their edge is given the same values of segment-distances and segment-weights as for the edge in the previous figure. And yet, the bendpoint is created (not accurately) but almost near to the expected location. Whereas the same value of segment-distance creates the bendpoint at the opposite location in the previous scenario.
I do not understand why this is happening. Can someone please guide me as how to solve this problem?
Refer to edge-distances:
edge-distances : With value intersection (default), the line from source to target for segment-weights is from the outside of the source node’s shape to the outside of the target node’s shape. With value node-position, the line is from the source position to the target position. The node-position option makes calculating edge points easier — but it should be used carefully because you can create invalid points that intersection would have automatically corrected.
https://js.cytoscape.org/#style/segments-edges
The intersection point is different from the node centre point (position).
If you want right-angled edges, you should probably just use taxi edges: https://js.cytoscape.org/#style/taxi-edges
Ok first off please see the post below:
Updating a record in Elm
I'm more curious as to how that is actually possible since that makes the record a variable in effect, something functional programming tries to avoid?
What happened to my old bill? Someone basically deleted my x = 4 and made a new one x = boo_far?
Functional programming avoids mutation. In Elm, records are not mutated, they are copied.
Even saying that they are copied is a bit of a misrepresentation. They are not fully cloned byte for byte. That would be horribly inefficient. Their internal structure is more graph-like, allowing for efficient pointer-based operations that effectively extend the underlying structures without mutating already-existing nodes and edges when you perform operations that copy into a new record.
Conceptually speaking, it may help to think of it this way: Once you copy into a new record value, the old one sticks around forever. However, our computers don't have infinite memory, and those old values may often go permanently unused, so we leave it to Javascript's garbage collector to clean up those old pointers.
Consider the example in the answer given by #timothyclifford:
-- Create Bill Gates
billGates = { age = 100, name = "gates" }
-- Copy to Bill Nye
billNye = { bill | name = "Nye" }
-- Copy to a younger Bill Nye
youngBillNye = { billNye | age = 22 }
The internal representation could be thought of like this:
Conceptually, you can think of those living in perpetuity. However, let's say that billGates gets selected for garbage deletion because it is no longer being referenced (e.g. its frame is popped from the stack). The billGates pointer is deleted and the name=="gates" node is deleted, but all other nodes and edges remain untouched:
So far, i have done a little bit of code for my project, but don't know whether its true or false. Can u guys see my code?? First at all, i should post the requirement for better understanding..
In computer science, mutual exclusion refers to the requirement of ensuring that no two processes or threads are in their critical section at the same time. A critical section refers to a period of time when the process accesses a shared resource, such as shared memory. The problem of mutual exclusion was first identified and solved by Edsger W. Dijkstra in 1965 in his paper titled: Solution of a problem in concurrent programming control.
For visual description of a problem see Figure. In the linked list the removal of a node is done by changing the “next” pointer of the preceding node to point to the subsequent node (e.g., if node i is being removed then the “next” pointer of node i-1 will be changed to point to node i+1). In an execution where such a linked list is being shared between multiple processes, two processes may attempt to remove two different nodes simultaneously resulting in the following problem: let nodes i and i+1 be the nodes to be removed; furthermore, let neither of them be the head nor the tail; the next pointer of node i-1 will be changed to point to node i+1 and the next pointer of node i will be changed to point to node i+2. Although both removal operations complete successfully, node i+1 remains in the list since i-1 was made to point to i+1 skipping node i (which was the node that reflected the removal of i+1 by having it's next pointer set to i+2). This problem can be avoided using mutual exclusion to ensure that simultaneous updates to the same part of the list cannot occur.
This is my code :
EXTENDS Naturals
CONSTANT Unlocked, Locked
VARIABLE P1,P2
TypeInvariant == /\ P1 \in {Unlocked,Locked}
/\ P2 \in {Unlocked,Locked}
Init == /\ TypeInvariant
/\ P1 = Unlocked
Remove1 == P2' = Locked
Remove2 == P1' = Locked
Next == Remove1 \/ Remove2
Spec == Init /\ [][Next]_<<P1,P2>>
THEOREM Spec => []TypeInvariant
First, what are you trying to model? It seems the only thing you are interested in proving as a theorem is the type invariant. I would have thought you want to prove something about mutual exclusion and not just the possible values of P1 and P2. For example, do you want to prove that P1 and P2 are never both locked at the same time?
MutualExclusion == ~(P1 = Locked /\ P2 = Locked)
THEOREM MutualExclusionTheorem == Spec => []MutualExclusion
Also, I wouldn't put TypeInvariant in the definition of Init. Your Init should contain the starting value(s) of your variables P1 and P2. Then you have a theorem,
THEOREM InitTypeInvariant == Init => TypeInvariant
and prove it. This theorem will be used in the proof of the theorem Spec.