Vec3 barycentric(const Vec3& value1, const Vec3& value2, const Vec3& value3, const float& amount1, const float& amount2) { return Vec3(barycentric(value1.x, value2.x, value3.x, amount1, amount2), barycentric(value1.y, value2.y, value3.y, amount1, amount2), barycentric(value1.z, value2.z, value3.z, amount1, amount2)); }
bool collides( SphereBody& body1, TriangleBody& body2, real_t collision_damping ) { // Normal vector of trangle body. Vector3 normal = normalize(cross(body2.vertices[1] - body2.vertices[0], body2.vertices[2] - body2.vertices[0])); real_t distance = dot(normal, body1.position - body2.position); // Sphere may come from the opposition direction of normal. if (std::abs(distance) <= body1.radius) { Vector3 projection = body1.position - distance * normal; Vector3 sphere_v = body1.velocity - body2.velocity; // If sphere moves toward the triangle, check whether it hits the surface or // edges of the triangle. if (dot(sphere_v, distance * normal) < 0 && (barycentric(projection, body2) || collides_vertices_axes(body1.position, body1.radius, body2))) { // Since the triangle is fixed, use the same formula with plane collision. real_t v_projection = dot(body1.velocity, normal); body1.velocity = body1.velocity - 2 * v_projection * normal; body1.velocity = (1 - collision_damping) * body1.velocity; return true; } } return false; }
Foam::vector Foam::barycentricParticle::position() const { vector centre; tensor A; tetTransform(centre, A); return fromBarycentric(A, centre, barycentric()); }
void Foam::barycentricParticle::position(const vector& position) { vector centre; scalar detA; tensor T; tetReverseTransform(centre, detA, T); barycentric() = toBarycentric(T/detA, centre, position); }
FT extrapolate(const Point &p, const Point &a, FT fa, const Point &b, FT fb, const Point &c, FT fc) { FT u, v, w; barycentric(p, a, b, c, u, v, w); return u * fa + v * fb + w * fc; }
void draw_triangle_gradient_new(point p[],vect_t zv[],double zs[],rgb c[]){ double minx=DBL_MAX,miny=DBL_MAX,maxx=-DBL_MAX,maxy=-DBL_MAX; for(int i=0;i<3;i++){ if( p[i].x < minx) minx=p[i].x; if( p[i].y < miny) miny=p[i].y; if( p[i].x > maxx) maxx=p[i].x; if( p[i].y > maxy) maxy=p[i].y; } vect_t t[3]; // printf("%f %f %f %f\n",minx,miny,maxx,maxy); for(int i=0;i<3;i++){ t[i].x=p[i].x; t[i].y=p[i].y; t[i].z=0; } #if BARY_INLINE // barycentric part one! vect_t u=v_sub(t[1],t[0]); vect_t v=v_sub(t[2],t[0]); double d=u.x*v.y-v.x*u.y,a,bb,cc; a=(u.y-v.y); bb=(v.x-u.x); cc=(u.x*v.y-v.x*u.y); #endif for(int y=miny;y<maxy;y++){ for(int x=minx;x<maxx;x++){ #if BARY_INLINE vect_t pt=v_sub((vect_t){(double)x,(double)y,0},t[0]); vect_t b; b.x=(pt.x*a+pt.y*bb+cc)/d; b.y=(pt.x*v.y-pt.y*v.x)/d; b.z=(pt.y*u.x-pt.x*u.y)/d; #else vect_t b=barycentric(t,(vect_t){(double)x,(double)y,0.0}); #endif // Fun effect if you put this at 0 #if 1 if(b.x < 0 || b.y < 0 || b.z < 0) continue; if(b.x > 1.0 || b.y > 1.0 || b.z > 1.0 ) continue; #else putpixel_c(x,y,c[0]); continue; #endif double z=b.x*zs[0] + b.y*zs[1] + b.z*zs[2]; rgb cout; cout.r=b.x*c[0].r + b.y*c[1].r + b.z*c[2].r; cout.g=b.x*c[0].g + b.y*c[1].g + b.z*c[2].g; cout.b=b.x*c[0].b + b.y*c[1].b + b.z*c[2].b; putpixel_3d(x,y,z,cout); // putpixel_c(x,y,c[0]) } } }
bool triangle_intersect(vector_t a, vector_t b, vector_t c, vector_t normal, vector_t ray_start, vector_t ray_direction, vector_t* hit, float* u, float* v, float* w) { vector_t plane_hit; if (!plane_intersect((plane_t) {a, normal}, ray_start, ray_direction, &plane_hit)) return false; float tmp_u, tmp_v, tmp_w; barycentric(a, b, c, normal, plane_hit, &tmp_u, &tmp_v, &tmp_w); if (tmp_u < 0.0 || tmp_v < 0.0 || tmp_w < 0.0) return false; *hit = plane_hit; *u = tmp_u; *v = tmp_v; *w = tmp_w; return true; }
Vec1 barycentric(const Vec1& value1, const Vec1& value2, const Vec1& value3, const float& amount1, const float& amount2) { return Vec1(barycentric(value1.x, value2.x, value3.x, amount1, amount2)); }
void draw_triangle_gradient(point p[],vect_t zv[],double zs[],rgb c[]){ int min_i=0,max_i=0,mid_i=-1; // for(int i=0;i<3;i++) print_point(p[i]); for(int i=1;i<3;i++){ if( p[i].x < p[min_i].x ) min_i=i; if( p[i].x > p[max_i].x ) max_i=i; } /* printf("min: "); print_point(p[min_i]); printf("max: "); print_point(p[max_i]); */ for(int i=0;i<3;i++) if( i != min_i && i != max_i ) mid_i = i; int dx0=p[min_i].x-p[max_i].x; int dy0=p[min_i].y-p[max_i].y; double k0=dy0/(float)dx0; int d0=p[min_i].y-k0*p[min_i].x; int dx1=p[min_i].x-p[mid_i].x; int dy1=p[min_i].y-p[mid_i].y; double k1=dy1/(float)dx1; int d1=p[min_i].y-k1*p[min_i].x; int dx2=p[mid_i].x-p[max_i].x; int dy2=p[mid_i].y-p[max_i].y; double k2=dy2/(float)dx2; int d2=p[mid_i].y-k2*p[mid_i].x; for(int x=p[min_i].x ;x<p[mid_i].x;x++){ int y0 = k0*x + d0; int y1 = k1*x + d1; for(int y=min(y0,y1);y<=max(y0,y1);y++){ point pc={x,y}; // color cc=_tri_calc_color(p,pc,c); vect_t b=barycentric(zv,(vect_t){x,y,0}); double z=b.x*zs[0] + b.y*zs[1] + b.z*zs[2]; if( x < 0 || x > WIDTH) continue; if( y < 0 || y > HEIGHT) continue; // printf("%f\n",z); // if((y>=0 && y<HEIGHT) && (x>0&&x<WIDTH)){ if(z_buffer[y*WIDTH+x] > z ){ putpixel_c(x,y,c[0]); z_buffer[y*WIDTH+x]=z; } } } } for(int x=p[mid_i].x ;x<p[max_i].x;x++){ int y0 = k0*x + d0; int y2 = k2*x + d2; for(int y=min(y0,y2);y<=max(y0,y2);y++){ point pc={x,y}; // color cc=_tri_calc_color(p,pc,c); // putpixel_c(x,y,c[0]); vect_t b=barycentric(zv,(vect_t){x,y,0}); //j double z=zv[0].z/b.x + zv[1].z/b.y + zv[2].z/b.z; double z = b.x*zs[0] + b.y*zs[1] + b.z*zs[2]; if( x < 0 || x > WIDTH) continue; if( y < 0 || y > HEIGHT) continue; if((y>=0 && y<HEIGHT) && (x>0&&x<WIDTH)){ if(z_buffer[y*WIDTH+x] > z){ putpixel_c(x,y,c[0]); z_buffer[y*WIDTH+x]=z; } } } } }