Class: Fastcluster::Clusterer

Inherits:
Object
  • Object
show all
Defined in:
ext/clusterer.c

Instance Method Summary collapse

Constructor Details

#new(separation = 0, resolution = 0, points = nil) ⇒ Object

Create a new Clusterer. The new method accepts 3 optional arguments, separation, resolution and points.

separation - The distance between clusters. The higher this number, the less clusters there will be. If this is 0 then no clustering will occur.

resolution - If specified then the points are placed on a grid with each grid square being this size. Points falling in the same grid square are automatically clustered. This option should be specified clustering larger number of points to reduce processing time.

points - An array of points. Each array item must be an array with two numbers (x, y). Example: [[1, 2], [3, 4]].



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'ext/clusterer.c', line 133

static VALUE fc_initialize_clusterer(int argc, VALUE *argv, VALUE self) {
  if(argc > 0)
    rb_iv_set(self, "@separation", argv[0]);
  else
    rb_iv_set(self, "@separation", INT2FIX(0));

  if(argc > 1)
    rb_iv_set(self, "@resolution", argv[1]);
  else
    rb_iv_set(self, "@resolution", INT2FIX(0));

  VALUE pointArray = rb_ary_new();
  rb_iv_set(self, "@points", pointArray);

  if(argc > 2) {
    if(TYPE(argv[2]) == T_ARRAY) {
      rb_iv_set(self, "@points", argv[2]);
    }
  }

  return Qnil;
}

Instance Method Details

#<<(point) ⇒ nil

Add a point to this clusterer. The point must be in the format of an array with two number.

Example:

clusterer << [1, 2]

Returns:

  • (nil)


65
66
67
68
69
# File 'ext/clusterer.c', line 65

static VALUE fc_append_point(VALUE self, VALUE point) {
  VALUE pointArray = fc_get_points(self);
  rb_ary_push(pointArray, point);
  return Qnil;
}

#add(x, y) ⇒ nil

Add a point to this clusterer.

Returns:

  • (nil)


46
47
48
49
50
51
52
53
# File 'ext/clusterer.c', line 46

static VALUE fc_add_point(VALUE self, VALUE x, VALUE y) {
  long len = 2;
  VALUE holdArray = rb_ary_new3(2, x, y);
  VALUE pointArray = fc_get_points(self);
  rb_ary_push(pointArray, holdArray);

  return Qnil;
}

#clustersObject

Return the clusters found for the points in this clusterer. This will be an array of Cluster objects.

Example:

clusterer = Fastcluster::Clusterer.new(3, 0, [[1, 1], [1, 2], [5, 9]])
clusterer.clusters -> [(1.00, 1.50): 2, (5.00, 9.00): 1]


311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# File 'ext/clusterer.c', line 311

static VALUE fc_get_clusters(VALUE self) {
  // Get the separation adn resolution from ruby
  long separation = NUM2INT(rb_iv_get(self, "@separation"));
  long resolution = NUM2INT(rb_iv_get(self, "@resolution"));
  int i;

  // Create a native array of clusters from the ruby array of points
  VALUE pointArray = fc_get_points(self);
  long num_points = RARRAY_LEN(pointArray);
  CLUSTER native_point_array[num_points];

  fc_native_point_array(&native_point_array[0], pointArray, num_points);

  // Calcualte the clusters
  CLUSTER * clusters = NULL;
  long cluster_size;

  clusters = fc_calculate_clusters(separation, resolution, &native_point_array[0], num_points, &cluster_size);

  // Create ruby array of clusters to return
  VALUE cluster_class = fc_get_cluster_class();
  VALUE ruby_cluster_array = rb_ary_new2(cluster_size);

  for(i=0;i<cluster_size;i++) {
    int arg_count = 3;
    VALUE arg_array[arg_count];

    arg_array[0] = rb_float_new(clusters[i].x);
    arg_array[1] = rb_float_new(clusters[i].y);
    arg_array[2] = INT2FIX(clusters[i].size);

    VALUE cluster_obj = rb_class_new_instance(arg_count, arg_array, cluster_class);
    rb_ary_push(ruby_cluster_array, cluster_obj);
  }

  // Free the clusters array
  free(clusters);

  return ruby_cluster_array;
}

#pointsObject

An array of points to be clustered.



36
37
38
# File 'ext/clusterer.c', line 36

static VALUE fc_get_points(VALUE self) {
  return rb_iv_get(self, "@points");
}