class Object
Public Instance Methods
contains_point?(*args)
click to toggle source
static VALUE c_contains_point(int argc, VALUE* argv, VALUE self) { VALUE respond_to = rb_intern("respond_to?"); VALUE p_x; VALUE p_y; switch (argc) { case 1: { VALUE arg = argv[0]; VALUE responds_x = rb_funcall(arg, respond_to, 1, ID2SYM(rb_intern("x"))); VALUE responds_y = rb_funcall(arg, respond_to, 1, ID2SYM(rb_intern("y"))); if (responds_x == Qtrue && responds_y == Qtrue) { p_x = rb_funcall(arg, rb_intern("x"), 0); p_y = rb_funcall(arg, rb_intern("y"), 0); } else { rb_raise(rb_eArgError, "Argument must respond to :x and :y."); } break; } case 2: { p_x = argv[0]; p_y = argv[1]; break; } default: break; } Check_Type(p_x, T_FLOAT); Check_Type(p_y, T_FLOAT); VALUE polygon = Qnil; switch (TYPE(self)) { case T_ARRAY: { polygon = self; break; } case T_OBJECT: { VALUE points_id = rb_intern("points"); VALUE responds = rb_funcall(self, respond_to, 1, ID2SYM(points_id)); if (responds == Qtrue) polygon = rb_funcall(self, points_id, 0); else rb_raise(rb_eTypeError, "Receiver does not respond to :points."); break; } default: rb_raise(rb_eTypeError, "Receiver is not a valid polygon."); break; } VALUE *poly_arr = RARRAY_PTR(polygon); int poly_len = RARRAY_LEN(polygon); if (poly_len < 3) rb_raise(rb_eTypeError, "Polygon must have at least 3 points"); double x = NUM2DBL(p_x); double y = NUM2DBL(p_y); //double *p_polygon = ALLOCA_N(double, 2 * poly_len); double *p_polygon = (double *)malloc(sizeof(double)*2*poly_len); for (int i = 0; i < poly_len; i++) { Check_Type(poly_arr[i], T_ARRAY); VALUE *p = RARRAY_PTR(poly_arr[i]); int p_len = RARRAY_LEN(poly_arr[i]); if (p_len != 2) rb_raise(rb_eTypeError, "A polygon's points must contain only two values."); Check_Type(p[0], T_FLOAT); Check_Type(p[1], T_FLOAT); p_polygon[i*2] = NUM2DBL(p[0]); p_polygon[(i*2)+1] = NUM2DBL(p[1]); } int res = pip((double (*)[2]) p_polygon, poly_len, x, y); free(p_polygon); return res == 1 ? Qtrue : Qfalse; }