# distribute edges on circle

## Recommended Posts

Is there a way in vex to make this king of circle with randomly distributed edges ?

CIRCLE.hiplc

##### Share on other sites

Do you actually want / need this in VEX, or do you just want the end result  (using just SOP)

##### Share on other sites

2 minutes ago, AntoineSfx said:

Do you actually want / need this in VEX, or do you just want the end result  (using just SOP)

Using just sop will be great too  I thought about vex thinking he should be easier

##### Share on other sites

This will merge two random adjacent primitives after each iteration.

deleteEdges.hipnc

##### Share on other sites

Here is another solution that allows to keep the prim structure.
Only sop, a bit convoluted IMO. I'm sure we can probably do better
I think it would be easier to use vex with the setedgegroup function.

Edited by flcc
##### Share on other sites

14 minutes ago, flcc said:

Here is another solution that allows to keep the prim structure.
It's a bit convoluted
I think it would be easier to use vex with the setedgegroup function.

I'd love to see a robust solution to " a random edge selection"..

I think I've seen that before with a conversion to line primitives with ConvertLines / Facet unique points, then a random selection among those primitives, and transfer back that subset as an edge group to the original geo, but I can't find a way to do this.

Edited by AntoineSfx
##### Share on other sites

Wonderful, thanks for your help !!

##### Share on other sites

I have Mega Exampel ... for education.

```#define TAU 6.283185307179586
#define PI  3.141592653589793

void segment(int   res_lon;
float start_theta;
float end_theta;
int   res_lat;
float start_phi;
float end_phi;
float r_min;
float r_max;
int ring_id;
int seg_id)
{
string poly_type = chs("poly_type");

float theta_step = (end_theta - start_theta) / (res_lon - 1);
float phi_step = (end_phi - start_phi) / (res_lat - 1);

int pt; // Keep track of last created point.

// Inner surface.
for (int i = 0; i < res_lat ; i++)
{
for (int j = 0; j < res_lon; j++)
{

// Calculate longitude arc point position.
float theta = start_theta + theta_step * j;
float phi = start_phi + phi_step * i;

matrix r = ident();
vector pos = set(cos(theta), 0, sin(theta)) * r_min;
vector axis = cross(normalize(pos), {0, 1, 0});
rotate(r, phi, axis);

pt = addpoint(geoself(), pos * r);
setpointattrib(geoself(), "ring_id", pt, ring_id, "set");
setpointattrib(geoself(), "seg_id", pt, seg_id, "set");

if (i > 0 && j > 0)
{

addvertex(geoself(), prim, pt - res_lon - 1);
}
}
}

// Outer surface. Same except r_max used and reversed vertex order.
for (int i = 0; i < res_lat ; i++)
{
for (int j = 0; j < res_lon; j++)
{
// Calculate longitude arc point position.
float theta = start_theta + theta_step * j;
float phi = start_phi + phi_step * i;

matrix r = ident();
vector pos = set(cos(theta), 0, sin(theta)) * r_max;
vector axis = cross(normalize(pos), {0, 1, 0});
rotate(r, phi, axis);

pt = addpoint(geoself(), pos * r);
setpointattrib(geoself(), "ring_id", pt, ring_id, "set");
setpointattrib(geoself(), "seg_id", pt, seg_id, "set");

if (i > 0 && j > 0)
{
// Create a new quad (reverse vertex order).
addvertex(geoself(), prim, pt - res_lon - 1);
}
}
}

// Side surfaces.
for (int i = 1; i < res_lon; i++)
{
int prim;
int surface_ptnum = res_lon * res_lat;
int start_pt = i + pt - surface_ptnum - surface_ptnum + 1;

// Bottom.
addvertex(geoself(), prim, start_pt - 1 + surface_ptnum);

// Top.
addvertex(geoself(), prim, start_pt + surface_ptnum - res_lon);
addvertex(geoself(), prim, start_pt - 1 + surface_ptnum - res_lon);
addvertex(geoself(), prim, start_pt - 1 + surface_ptnum + surface_ptnum - res_lon);
addvertex(geoself(), prim, start_pt + surface_ptnum + surface_ptnum - res_lon);
}

for (int i = 1; i < res_lat; i++)
{
int prim;
int surface_ptnum = res_lon * res_lat;
int start_pt = i * res_lon + pt - surface_ptnum - surface_ptnum + 1;

// Side A.
addvertex(geoself(), prim, start_pt - res_lon + surface_ptnum);

// Side B.
addvertex(geoself(), prim, start_pt - 1 + res_lon);
addvertex(geoself(), prim, start_pt - 1 + res_lon + surface_ptnum);
addvertex(geoself(), prim, start_pt - 1 + surface_ptnum);
}

}

// RING FUNCTION

void ring(float min_arc;
float max_arc;
float h_min;
float h_max;
float r_min;
float r_max;
float skip_chance;
int   ring_id;
float ring_seed;
int num_rings;
float frame){

float fixed_res = chi("fixed_res");
float step_lon = ch("step_lon")+10000*fixed_res; // Longitude resolution in meters.
float step_lat = ch("step_lat")+10000*fixed_res; // Latitude resolution in meters.

float theta = 0;
float in_theta = 0; // ch("test_theta_step");  //start_theta
float out_theta = theta + TAU;
float arc_width;

float phi = 0;
float arc_h;
float freq_min = ch("freq1"); //height change frequency
float freq_max = ch("freq2");

float sfreq_min = ch("sfreq1"); //spin frequency
float sfreq_max = ch("sfreq2");
float amp_min = ch("amp1");
float amp_max = ch("amp2");

//int seg_num = npoints(geoself()); // /(res_lon+1*res_lat+1)
int seg_id = 0;

float f = frame; //ch("t"); //time frame

//ring logic
while (1) {

//seeds and mapping
float seed = seg_id + ring_seed;
float seed_big = fit(rand(seed+2153.5),0,1, 0, 50000);
float nr_max = fit(rand(r_max), 0, 1, 0.2, 1);
float ring_idf = fit(ring_id, 0, num_rings, 0, 1);

arc_width = fit(rand(seed+223),0,1, min_arc, max_arc);
float arc_sep = fit(rand(seed+536),0,1, arc_sep_min, arc_sep_max);

// check end of circle doesn't overlap begin
if (theta+arc_width >= TAU-arc_sep){
arc_width = TAU-theta-arc_sep*nr_max; //
}

//noise fx for height
float freq = chramp("freq_ramp", rand(seed_big+8+ring_idf));
freq = fit(freq,0,1, freq_min, freq_max);
float sample = (f/2)*freq;
float noise = noise(sample);

//height
arc_h = fit(noise,0.3,1,h_min,h_max);
float m = arc_h*ch("mirror"); //mirror below xz plane

//noise fx for rotation
int crazy_spin = chi("crazy_spin"); //crazy_spinning is seeded per segment, this causes segments overlapping
float sfreq = chramp("spin_ramp", ring_idf+rand(seed_big+0.5)*crazy_spin); //spin frequency ramped on ring id
sfreq = fit(sfreq,0,1, sfreq_min, sfreq_max);
float sample1 = f*sfreq;
float noise1 = noise(sample1);
float spin_rnd = fit(noise1,0.3,1,0,1);

//trig fx for rotation
float spin_trig = sin(sample1);
spin_trig = fit(spin_trig,-1,1,0,1);

//regular rotation
float spin_reg = f*sfreq; //in this case sfreq is the slope of the linear curve

//rotation
float amp = fit(rand(ring_seed+1.25),0,1,amp_min,amp_max);
int spin_dir = (rand(ring_seed+11) > 0.5) ? 1 : -1;
amp *= spin_dir;  //clock and counterclock turn

float w;
int spin_type = chi("spin_type");
if (spin_type == 0){
w = amp*spin_reg/5; // /5 is for keeping rotational speed similar to other types
}
if (spin_type == 1){
w = amp*spin_rnd;
}
if (spin_type == 2){
w = amp*spin_trig;
}

in_theta = w+amp; //+amp gives a in_theta offset foreach ring even when rotation is disabled

// Proportional longitude resolution.
float arc_width_length = r_max * radians(arc_width)*10;
int res_lon = max((int) (arc_width_length / step_lon), chi("min_res1"));

// Proportional longitude resolution.
float arc_h_length = r_max * radians(arc_h)*10;
int planar = chi("planar"); //flat rings
int res_lat = max((int) (arc_h_length / step_lat), chi("min_res2"))*(1-planar)+planar;

//creation
if (rand(seed+1563.9) > skip_chance )
{
segment(res_lon, in_theta+theta, in_theta+theta+arc_width, res_lat, phi-m, phi+arc_h, r_min, r_max, ring_id, seg_id);
}

theta += arc_width+arc_sep; // arc separation
seg_id +=1 ;

if (theta>= out_theta)
break;
}
}

float r_min = ch("r1");
float r_max = ch("r2");
float skip_chance = ch("skip_chance"); //chance to make a hole in ring
float frame = @Frame;

// ENTIRE RING SYSTEM

int num_rings = chi("ring_count");
float ring_seed = ch("seed_ring");
float r_depth_min = ch("r_depth1");
float r_depth_max = ch("r_depth2");
float r_depth_seed = ch("r_depth_seed");
float off_min = ch("ring_off1");
float off_max = ch("ring_off2");
float r_off_seed = ch("ring_off_seed");

for (int i=0; i<num_rings; i++) {

float r_depth = fit(rand(i+r_depth_seed+222),0,1,r_depth_min,r_depth_max);
float r_off = fit(rand(i+r_off_seed+.5),0,1,off_min,off_max);

ring(min_arc, max_arc, min_h, max_h, r_min, r_max, skip_chance, i, ring_seed, num_rings, frame);

r_min = r_max+r_off;
r_max = r_min+r_depth;
ring_seed *=1.235684;
}```

##### Share on other sites

here's my go...does not rely on existing (discrete) segments to make cuts, does not merge and therefore no interpolation, the cuts are exactly where they are. Will work even with extremely thin cuts.

alright alright, exact is a dirty word...who knows what Boolean is doing behind the scene but I'll place blind trust in boolean to its job.

Edited by Noobini

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×