Example #1
0
static struct cpShapeMassInfo
cpSegmentShapeMassInfo(cpFloat mass, cpVect a, cpVect b, cpFloat r)
{
	struct cpShapeMassInfo info = {
		mass, cpMomentForBox(1.0f, cpvdist(a, b) + 2.0f*r, 2.0f*r), // TODO is an approximation.
		cpvlerp(a, b, 0.5f),
		cpAreaForSegment(a, b, r),
	};
	
	return info;
}
Example #2
0
static cpBody *utils_update_drawing(cpBody *drawing) {
    cpFloat mass = cpBodyGetMass(drawing);
    cpFloat moment = cpBodyGetMoment(drawing);
    
    Body_data *pa = cpBodyGetUserData(drawing);
    //cpFloat x = g_array_index(pa->x_values, cpFloat, 0);
    //cpFloat y = g_array_index(pa->y_values, cpFloat, 0);
    
    cpVect pos_a, pos_b;
    cpVect origin = cpBodyGetPos(drawing);
    
    cpFloat mi, micx = 0, micy = 0;
    int length = pa->x_values->len;
    for (int index = 1; index < length; index++) {
        pos_a = cpv(g_array_index(pa->x_values, cpFloat, index - 1), g_array_index(pa->y_values, cpFloat, index - 1));
        pos_b = cpv(g_array_index(pa->x_values, cpFloat, index), g_array_index(pa->y_values, cpFloat, index));
	 	//fprintf(stdout, "Pos_a = (%5.2f, %5.2f)\n", pos_a.x, pos_a.y);
		
        mi = (CRAYON_MASS * cpAreaForSegment( pos_a, pos_b, CRAYON_RADIUS ));
        micx += mi * ((pos_a.x + pos_b.x) / 2);
        micy += mi * ((pos_a.y + pos_b.y) / 2);
        
        mass += mi;
        moment += cpMomentForSegment(mass, pos_a, pos_b); // not actually sum, but maybe it is
    }

    cpBodySetMass(drawing, mass);
    cpBodySetMoment(drawing, moment);
    
    // center of mass is the average of all vertices  NOT
    //cpVect new_origin = cpv(x / length, y / length);
    cpVect new_origin = cpv(micx / mass, micy / mass);
    new_origin = cpBodyLocal2World(drawing, new_origin);
    cpBodySetPos( drawing, new_origin );
	//fprintf(stdout, "Position set at (%5.2f, %5.2f)\n", new_origin.x, new_origin.y);
    cpSpace * space = cpBodyGetSpace(drawing);
	cpSpaceReindexShapesForBody(space, drawing);
    //cpBodySetPos(drawing, cpv(pos.x + (second.x / length), pos.y + (second.y / length)));
    //pa->offset = cpvsub(new_origin, origin);
    pa = shift_origin(drawing, origin, new_origin);
    cpBodySetUserData(drawing, pa);
	if (space)
		post_step_body_replace_shapes(space, drawing, NULL);
	else
		fprintf(stderr, "WTF\n");

	//if (!(cpSpaceAddPostStepCallback(space, (cpPostStepFunc) post_step_body_replace_shapes, drawing, NULL)))
		//fprintf(stderr, "FAILED POST-STEP CALLBACK\n\n");
	
    return drawing;
}
Example #3
0
/**	@name	areaForSegment
	@text	Returns the area for the specified segment.

	@in		number x1
	@in		number y1
	@in		number x2
	@in		number y2
	@in		number r
	@out	number area			The calculated area.
*/
int MOAICpShape::_areaForSegment ( lua_State* L ) {
	USLuaState state ( L );
	if ( !state.CheckParams ( 1, "UUNNNN" )) return 0;
	
	cpVect a;
	a.x = state.GetValue < cpFloat >( 1, 0 );
	a.y = state.GetValue < cpFloat >( 2, 0 );
	
	cpVect b;
	b.x = state.GetValue < cpFloat >( 3, 0 );
	b.y = state.GetValue < cpFloat >( 4, 0 );

	cpFloat r = state.GetValue < cpFloat >( 5, 0 );

	lua_pushnumber ( L, cpAreaForSegment ( a, b, r ));
	return 1;
}
Example #4
0
static cpBody *utils_update_drawing(cpBody *drawing) {
    cpFloat mass = cpBodyGetMass(drawing);
    cpFloat moment = cpBodyGetMoment(drawing);
    
    Point_array *pa = cpBodyGetUserData(drawing);
    cpFloat x = g_array_index(pa->x_values, cpFloat, 0);
    cpFloat y = g_array_index(pa->y_values, cpFloat, 0);
    
    cpVect pos_a, pos_b;
    cpVect origin = cpBodyGetPos(drawing);
    
    cpFloat mi, micx = 0, micy = 0;
    int length = pa->x_values->len;
    for (int index = 1; index < length; index++) {
        pos_a = cpv(g_array_index(pa->x_values, cpFloat, index - 1), g_array_index(pa->y_values, cpFloat, index - 1));
        pos_b = cpv(g_array_index(pa->x_values, cpFloat, index), g_array_index(pa->y_values, cpFloat, index));
 	cpvadd(pos_a, origin);
	cpvadd(pos_b, origin);       
        x += pos_b.x;
        y += pos_b.y;
        
        mi = (CRAYON_MASS * cpAreaForSegment( pos_a, pos_b, CRAYON_RADIUS ));
        micx += mi * ((pos_a.x + pos_b.x) / 2);
        micy += mi * ((pos_a.y + pos_b.y) / 2);
        
        mass += mi;
        moment += cpMomentForSegment(mass, pos_a, pos_b); // not actually sum
    }

    cpBodySetMass(drawing, mass);
    cpBodySetMoment(drawing, moment);
    
    // center of mass is the average of all vertices  NOT
    //cpVect new_origin = cpv(x / length, y / length);
    cpVect new_origin = cpv(micx / mass, micy / mass);
    cpBodySetPos( drawing, new_origin );
    //cpBodySetPos(drawing, cpv(pos.x + (second.x / length), pos.y + (second.y / length)));
    
    pa = shift_origin(pa, origin, new_origin);
    cpBodySetUserData(drawing, pa);
    
    return drawing;
}
Example #5
0
cpFloat Area::ForSegment( cVect a, cVect b, cpFloat r ) {
	return cpAreaForSegment( tocpv( a ), tocpv( b ), r );
}
Example #6
0
__declspec( dllexport ) void areaforsegment( const void * _in, int in_size, void * _out, int out_sz )
{

	POKEFLOAT(OUTPUT_MEMBLOCK,0,cpAreaForSegment(PEEKVECT(INPUT_MEMBLOCK,0),PEEKVECT(INPUT_MEMBLOCK,8),PEEKFLOAT(INPUT_MEMBLOCK,16)));
}
Example #7
0
static VALUE
rb_cpAreaForSegment(VALUE self, VALUE v1, VALUE v2, VALUE r) {
  cpFloat i = cpAreaForSegment(*VGET(v1), *VGET(v2), NUM2DBL(r));
  return rb_float_new(i);
}