D3 Chord Diagram Not Rendering Correctly - d3.js

Using the excellent guide by Nadieh Bremer I'm making a stretched chord diagram.
However, with certain data inputs the rendering goes awry.
I've made a demo to demonstrate my issue here:
https://codepen.io/benmayocode/pen/MPEwdr
Specifically, in the .js file lines 269 to 281 file I have:
var respondents = 40,
emptyPerc = 0.4,
emptyStroke = Math.round(respondents*emptyPerc);
var Names = ['BEN', 'ROSE', '', '1', '2', '6', ''];
var matrix = [
[0, 0, 0, 10, 10, 0, 0] ,
[0, 0, 0, 0, 10, 10, 0] ,
[0, 0, 0, 0, 0, 0, 24] ,
[10, 0, 0, 0, 0, 0, 0] ,
[10, 10, 0, 0, 0, 0, 0] ,
[0, 10, 0, 0, 0, 0, 0] ,
[0, 0, 0, 24, 0, 0, 0] ,
];
This renders incorrectly - but if I change it to...
var respondents = 40,
emptyPerc = 0.4,
emptyStroke = Math.round(respondents*emptyPerc);
var Names = ['BEN', 'LIB', 'ROSE', '', '1', '2', '6', ''];
var matrix = [
[0, 0, 0, 0, 10, 10, 0, 0] ,
[0, 0, 0, 0, 0, 10, 0, 0] ,
[0, 0, 0, 0, 0, 10, 10, 0] ,
[0, 0, 0, 0, 0, 0, 0, 24] ,
[10, 0, 0, 0, 0, 0, 0, 0] ,
[10, 10, 10, 0, 0, 0, 0, 0] ,
[0, 0, 10, 0, 0, 0, 0, 0] ,
[0, 0, 0, 0, 24, 0, 0, 0] ,
];
Then it works great. I obviously see the difference between the two blocks of code, but why are they producing different results, and is it possible to modify my code to accommodate both examples?

If you examine the dodgy arc, you will see you can flip it into the right place by altering the sign on the transform from (50,0) to (-50,0). If you then look at the code that assigns the transform, it is
.attr("transform", function(d, i) {
d.pullOutSize = pullOutSize * ( d.startAngle + 0.01 > Math.PI ? -1 : 1);
return "translate(" + d.pullOutSize + ',' + 0 + ")";
});
with a note in the original text to say that "the 0.01 is for rounding errors". Given that the startAngle is already 3.13--i.e. very close to Pi--it looks like this is an edge case where the value fell just the wrong side of the cutoff. Changing the allowable rounding error value to 0.02 puts the arc in the correct place, or you could do something like
d.pullOutSize = pullOutSize * (
// is the start angle less than Pi?
d.startAngle + 0.01 < Math.PI ? 1 :
// if yes, is the end angle also less than Pi?
d.endAngle < Math.PI ? 1 : -1 );
to prevent edge cases like that in your dataset.

Related

Gridmap Node set_cell_item() rotation of the tile object

I'm developing a procedural map using gridmap 3D in Godot,
set_cell_item(x: int, y: int, z: int, item: int, orientation: int = 0)
On the last property I can setup the orientation, of the object... but it looks like it ranges from -1 to 1...so, only 3 options?
Using then make my tile rotate in the Z axis, and I want it to rotate on the y axis. The docs point me to
get_orthogonal_index()
But I dindt understand how to use it
The value goes from 0 to 24, where 0 is no rotation. The documentation of get_orthogonal_index says:
This function considers a discretization of rotations into 24 points on unit sphere, lying along the vectors (x,y,z) with each component being either -1, 0, or 1, and returns the index of the point best representing the orientation of the object. It is mainly used by the GridMap editor. For further details, refer to the Godot source code.
What the 24 rotations are is not easy to visualize. However, suffice to say they are the The Rotational Symmetries of the Cube. In other words, they are all the ways you can take a nondescript cube and rotate it, such that it looks the same after the rotation (it is rotated, but being a nondescript cube, it looks the same).
Now, the issue is in what order are these rotations?
Well, wonder no more, thanks to the magic of looking at Godot source code, these are the rotations:
// --- x --- --- y --- --- z ---
Basis( 1, 0, 0, 0, 1, 0, 0, 0, 1), // 0
Basis( 0, -1, 0, 1, 0, 0, 0, 0, 1), // 1
Basis(-1, 0, 0, 0, -1, 0, 0, 0, 1), // 2
Basis( 0, 1, 0, -1, 0, 0, 0, 0, 1), // 3
Basis( 1, 0, 0, 0, 0, -1, 0, 1, 0), // 4
Basis( 0, 0, 1, 1, 0, 0, 0, 1, 0), // 5
Basis(-1, 0, 0, 0, 0, 1, 0, 1, 0), // 6
Basis( 0, 0, -1, -1, 0, 0, 0, 1, 0), // 7
Basis( 1, 0, 0, 0, -1, 0, 0, 0, -1), // 8
Basis( 0, 1, 0, 1, 0, 0, 0, 0, -1), // 9
Basis(-1, 0, 0, 0, 1, 0, 0, 0, -1), // 10
Basis( 0, -1, 0, -1, 0, 0, 0, 0, -1), // 11
Basis( 1, 0, 0, 0, 0, 1, 0, -1, 0), // 12
Basis( 0, 0, -1, 1, 0, 0, 0, -1, 0), // 13
Basis(-1, 0, 0, 0, 0, -1, 0, -1, 0), // 14
Basis( 0, 0, 1, -1, 0, 0, 0, -1, 0), // 15
Basis( 0, 0, 1, 0, 1, 0, -1, 0, 0), // 16
Basis( 0, -1, 0, 0, 0, 1, -1, 0, 0), // 17
Basis( 0, 0, -1, 0, -1, 0, -1, 0, 0), // 18
Basis( 0, 1, 0, 0, 0, -1, -1, 0, 0), // 19
Basis( 0, 0, 1, 0, -1, 0, 1, 0, 0), // 20
Basis( 0, 1, 0, 0, 0, 1, 1, 0, 0), // 21
Basis( 0, 0, -1, 0, 1, 0, 1, 0, 0), // 22
Basis( 0, -1, 0, 0, 0, -1, 1, 0, 0) // 23
These are Basis. They describe the orientation by specifying the direction of the axis.
The three first numbers are the x axis, followed by three numbers for the y axis, and three more for the z axis.
The first one, is no rotation at all:
Basis( 1, 0, 0, 0, 1, 0, 0, 0, 1), // 0
Notice that the x axis is 1,0,0, which means it is oriented towards the x. The y axis is 0,1,0… you guested oriented towards the y, and 0,0,1 for the z being just the z. So no rotation, as expected.
As you can see the first four indexes gives you rotation that keep the z axis untouched. Thus, you see rotation around the z axis.
Since you want rotation around the y axis, let us pick the ones that keep the y axis untouched:
Basis( 1, 0, 0, 0, 1, 0, 0, 0, 1), // 0
Basis(-1, 0, 0, 0, 1, 0, 0, 0, -1), // 10
Basis( 0, 0, 1, 0, 1, 0, -1, 0, 0), // 16
Basis( 0, 0, -1, 0, 1, 0, 1, 0, 0), // 22
As per the order… 0 is no rotation. 10 is half turn, since the other axis are flipped. Thus, either 0, 22, 10, 16 or 0, 16, 10, 22, depending if you want a positive or negative rotation.

How can I create a random array between a range of two other arrays?

I need to generate an array of random 20 bytes between a given range of arrays. Since arrays are comparable in Rust, this works:
let low = [0u8; 20];
let high = [2u8; 20];
assert_eq!(true, low < high);
assert_eq!(false, low > high);
assert_eq!(true, low == [0u8; 20]);
For these bounds:
let low: [u8; 20] = [98, 0, 1, 0, 2, 6, 99, 3, 0, 5, 23, 3, 5, 6, 11, 8, 0, 2, 0, 17];
let high: [u8; 20] = [99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
These would be a valid result:
[98, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
These are not:
[98, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]
I want to do something like:
use rand::prelude::*;
fn main() {
let low = [0u8; 20];
let high = [2u8; 20];
let value = rand::thread_rng().gen_range(low, high);
println!("{:?}", value);
}
but I get following error:
error[E0277]: the trait bound `[u8; 20]: rand::distributions::uniform::SampleUniform` is not satisfied
--> src\main.rs:6:36
|
6 | let value = rand::thread_rng().gen_range(low, high);
| ^^^^^^^^^ the trait `rand::distributions::uniform::SampleUniform` is not implemented for `[u8; 20]`
I tried implementing SampleUniform and UniformSampler without much success. Is there a simple way to implement this?
If you want to treat the byte arrays as big integers, use the
num-bigint crate with the rand feature enabled:
use bigint::{ToBigInt, RandBigInt};
let low = -10000.to_bigint().unwrap();
let high = 10000.to_bigint().unwrap();
let b = rng.gen_bigint_range(&low, &high);
You could also use unsigned integers instead of signed. There are methods to convert to and from big endian byte arrays:
from_bytes_be
to_bytes_be
See also:
How do I generate a random num::BigUint?

How to find boundary point using bfs algorithm

I think of the 2D array as a coordinate and try to find a coordinate value with a value of 1.
So far, it's a very easy BFS problem, but what I want to do is look at the following picture.
While I'm looking for 1 or after I've found it all, I would like to know the coordinate values surrounding the boundary in the order of the arrow or the other direction.
What options do I need to add to get those information?
Below is the BFS code that I use now. I can get coordinate values from the BFS function as shown in the second picture.
class Node
{
public int x;
public int y;
public Node(int x, int y)
{
this.x = x;
this.y = y;
}
};
private int[] dx = new int[8] { -1, 0, 1, 0, 1, -1, -1, 1 };
private int[] dy = new int[8] { 0, -1, 0, 1, 1, -1, 1, -1 };
private Queue<Node> q = new Queue<Node>();
bool[,] visit = new bool[15, 15];
int[,] coordinates = new int[15, 15] { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }};
void BFS(int[,] pixel, int x, int y)
{
q.Enqueue(new Node(x, y));
visit[x, y] = true;
while (q.Count != 0)
{
Node cur = q.Dequeue();
for (int i = 0; i < 8; i++)
{
int r = cur.x + dx[i];
int c = cur.y + dy[i];
if (r >= 0 && c >= 0 && r < 15 && c < 15)
{
if (!visit[r, c] && pixel[r, c] == 1)
{
q.Enqueue(new Node(r, c));
visit[r, c] = true;
}
}
}
}
}
void main()
{
for (int y = 0; y < 15; y++)
{
for (int x = 0; x < 15; x++)
{
if (!visit[x, y] && coordinates[x, y] == 1)
{
BFS(coordinates, x, y);
}
}
}
}
we do not need BFS for finding boundary '1' values. We can simply loop over 2D grid and then for each '1', we can just check whether all of it's 4 adjacent (i.e up, down, left, right) values are '1' or not. If at least one of them is not '1', then it is a boundary point. Thanks!
find a coordinate value with a value of 1
Start by pre-processing the matrix
- Search all 1 values (this can also be done recursively)
- If 1 value does not have a 0 neighbor, it means it it not on edge - change it to 0.
After the pre-processing you are left with only the edge 1 values, and all others are 0.
I would like to know the coordinate values surrounding the boundary in
the order of the arrow or the other direction
To find out if the edge forms a closed loop, and get the nodes in the right order
apply BFS to the pre-processed matrix.
Seek a path from a node of your choice, back to the same node(a loop).

How to remove elements from a 3D array in ruby [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I am trying to remove first element from the every 1D array in the 1st, 2nd and 5th column.
The 3D array looks like
1st col 2nd col 3rd col 4th col 5th col
[
[[0, 0, 0, 2, 3, 0, 0, 5], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]]
]
Desired 3D array should look like
1st col 2nd col 3rd col 4th col 5th col
[
[[ 0, 0, 2, 3, 0, 0, 5], [ 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0]],
[[ 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0]],
[[ 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0]],
[[ 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0]],
[[ 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0]],
[[ 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0]],
[[ 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0]],
[[ 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0]]
]
I am not sure what is best way to do this in ruby.
If I understand your question correctly, you can do the following, where arr is your array:
arr_cpy = Marshal.load(Marshal.dump(arr))
[0,1,4].each { |i| arr_cpy[i] = arr_cpy[i].transpose[1..-1].transpose }
arr_cpy
I've used Marshal#dump and Marshal#load to make a "deep copy" of arr, so that arr will not be altered ("mutated"). If you wish to mutate arr, simply skip that step and change arr_cpy to arr in the second line.
Try this:
array.map do |row_of_column_arrays|
row_of_column_arrays.each_with_index.map do |column_arr, index|
[0, 1, 4].include?(index) ? column_arr[1..-1] : column_arr
end
end
Bottom-up, your array is made out of the following dimensions:
(1) Cell
(2) Column Array (e.g. [0,0,0,2,3,0,0,5])
(3) Row of Column Array (e.g. the first row in your question)
(4) Array of Rows of Column Array (this is the value residing in array.
So, the first map is applied on #4 and goes over each Row of Column Arrays (3). For each of this we run the second map method, which goes over each Column Array (2). We simply return from that block that particular Column Array without the first element, if we are dealing with indices 0, 1, and 4 (corresponding to 1st, 2nd and 5th columns):
[0,0,0,2,3,0,0,5][1..-1]
# => [0,0,2,3,0,0,5]

How to push a value into a multi-dimensional array (RUBY)

I'm looking to push the value 1 into an array of all 0's at a random index point.
The format of the array is a 10 by 10 lot of 0's arranged into a square table. I want to generate a random input point for this, and change that value to 1.
You can try as below :-
# First create an array of array
array = Array.new(10) { Array.new(10) { 0 } }
# method to get the random index.
def random_index(start_point = 0, end_point)
(start_point..end_point).to_a.sample
end
# First find out the any random inner array
inner_array = array[random_index(0, array.size-1)]
# Then get the any random index from the inner array and update the value.
inner_array[random_index(0, array.size-1)] = 1
array
# => [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
To answer the OP's comment :-
def get_index_of_item_from_inner_array(array, item)
first_inner_array_contains_item = array.find { |in_ary| in_ary.include? item }
(0..first_inner_array_contains_item.size - 1).find { |ind| first_inner_array_contains_item[ind] == item }
end
get_index_of_item_from_inner_array(array, 1) # => 2
One way:
arr = Array.new(10) { Array.new(10) { 0 } }
row, col = rand(100).divmod(10)
arr[row][col] = 1
row #=> 7
col #=> 6
arr
#=> [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

Resources