Jump to content

distribute edges on circle


davidyannick

Recommended Posts

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.

Dissolve random  int edges.JPG

CIRCLE F.hiplc

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
  • Like 1
Link to comment
Share on other sites

I have Mega Exampel ... for education. :wub:

#define TAU 6.283185307179586
#define PI  3.141592653589793

addpointattrib(geoself(), "ring_id", -1);
addpointattrib(geoself(), "seg_id", -10);

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)
            {
                // Create a new quad.
                int prim = addprim(geoself(), poly_type);

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

    // 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).
                int prim = addprim(geoself(), poly_type);
                addvertex(geoself(), prim, pt);
                addvertex(geoself(), prim, pt - 1);
                addvertex(geoself(), prim, pt - res_lon - 1);
                addvertex(geoself(), prim, pt - res_lon);
            }
        }
    }

    // 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.
        prim = addprim(geoself(), poly_type);
        addvertex(geoself(), prim, start_pt - 1);
        addvertex(geoself(), prim, start_pt);
        addvertex(geoself(), prim, start_pt + surface_ptnum);
        addvertex(geoself(), prim, start_pt - 1 + surface_ptnum);

        // Top.
        prim = addprim(geoself(), poly_type);
        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.
        prim = addprim(geoself(), poly_type);
        addvertex(geoself(), prim, start_pt);
        addvertex(geoself(), prim, start_pt - res_lon);
        addvertex(geoself(), prim, start_pt - res_lon + surface_ptnum);
        addvertex(geoself(), prim, start_pt + surface_ptnum);

        // Side B.
        prim = addprim(geoself(), poly_type);
        addvertex(geoself(), prim, start_pt - 1);
        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 arc_sep_min = radians(ch("arc_sep1"));
      float arc_sep_max = radians(ch("arc_sep2"));
            
      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 min_arc = radians(ch("arc1"));
float max_arc = radians(ch("arc2"));
float min_h = radians(ch("height1"));
float max_h = radians(ch("height2"));
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;        
}

 

  • Like 2
Link to comment
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.

vu_RandomPieCuts.hiplc

RandomPieCuts.gif

Edited by Noobini
  • Like 3
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

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

×
×
  • Create New...