void LineShape2D::draw(const RID &p_to_rid, const Color &p_color) { Vector2 point = get_d() * get_normal(); Vector2 l1[2] = { point - get_normal().tangent() * 100, point + get_normal().tangent() * 100 }; VS::get_singleton()->canvas_item_add_line(p_to_rid, l1[0], l1[1], p_color, 3); Vector2 l2[2] = { point, point + get_normal() * 30 }; VS::get_singleton()->canvas_item_add_line(p_to_rid, l2[0], l2[1], p_color, 3); }
Rect2 LineShape2D::get_rect() const { Vector2 point = get_d() * get_normal(); Vector2 l1[2] = { point - get_normal().tangent() * 100, point + get_normal().tangent() * 100 }; Vector2 l2[2] = { point, point + get_normal() * 30 }; Rect2 rect; rect.pos = l1[0]; rect.expand_to(l1[1]); rect.expand_to(l2[0]); rect.expand_to(l2[1]); return rect; }
Triangle::Triangle(int p1_idx, int p2_idx, int p3_idx) { p1 = World::points[p1_idx]; p2 = World::points[p2_idx]; p3 = World::points[p3_idx]; get_normal(); }
vec3 calculate_color(const distance& dist, const vec3& p, const vec3& ray, const int userdata) { vec3 normal = get_normal(dist.field, p); const float eta = 0.3; const float sqf = (1 - eta) / (1 + eta); const float f = sqf * sqf; const float fresnel_power = 5; const float ratio = f + (1 - f) * pow(1 - dot(ray, normal), fresnel_power); vec3 diffuse = get_color(dist.object_id, p); if (dist.object_id == 2 && userdata < 3) { vec3 reflect_ray = glm::reflect(ray, normal); diffuse = mix(diffuse, raymarch(p + reflect_ray * 0.01f, reflect_ray, userdata + 1), ratio); } vec3 color(0.1); for (vec3 light : get_lights()) { const vec3 light_dir = normalize(p - light); const float light_dist = glm::distance(p, light); color += max(dot(normal, light_dir), 0.0f) * diffuse; const vec3 half = normalize(light_dir + ray); color += pow(max(dot(normal, half), 0.0f), 64.0f); color *= softshadow(p, -light_dir, 0.1, light_dist, 64) * 0.7 + 0.3; } //color *= mix(vec3(1), get_background_color(), 0.5 + 0.5 * dot(normal, vec3(0, -1, 0))); //color = pow(color, vec3(0.45f)); color = clamp(color, 0.0f, 1.0f); return color; }
bool triangle3<T>::is_front_facing(const vec3<T>& lookDirection) const { const vec3<T> n = get_normal(); n.normalize(); const T d = dot(n, lookDirection); return F32_LOWER_EQUAL_0(d); }
inline void glFace3f(const Point3f &point1, const Point3f &point2, const Point3f &point3) { Point3f normal = get_normal(point1, point2, point3); glNormal3f(normal.x, normal.y, normal.z); glVertex3f(point1.x, point1.y, point1.z); glVertex3f(point2.x, point2.y, point2.z); glVertex3f(point3.x, point3.y, point3.z); }
bool box::hit(const ray& r, hit_record* hr) const { vec3 rrd = 1.f / r.d; vec3 t1 = (box_bounds._min - r.e) * rrd; vec3 t2 = (box_bounds._max - r.e) * rrd; vec3 m12 = glm::min(t1, t2); vec3 x12 = glm::max(t1, t2); float tmin = m12.x; tmin = glm::max(tmin, m12.y); tmin = glm::max(tmin, m12.z); float tmax = x12.x; tmax = glm::min(tmax, x12.y); tmax = glm::min(tmax, x12.z); if (tmax < tmin || tmin < 0) return false; if(hr == nullptr) return true; if(tmin > hr->t) return false; vec3 p = r(tmin); vec3 n = get_normal(p); uint mci = 0; for (int i = 0; i < 3; ++i) if (n[i] != 0.f) mci = i; vec3 dpdu, dpdv; dpdu[(mci - 1) % 3] = 1.f; dpdv[(mci + 1) % 3] = 1.f; hr->set(this, tmin, n, vec2(p[(mci-1)%3], p[(mci+1)%3]), dpdu, dpdv); return true; }
t_color compute_light(t_scene *scene, t_ray *ray) { t_list *current; t_ray lray; t_color color[3]; t_phpa ph; current = scene->lights; ph.normal = get_normal(*ray); set_ambiant_light(&ph, scene, ray, color); while (current) { lray.pos = ((t_light *)current->content)->pos; lray.dir = norm_vect(mtx_add(mtx_sub(mtx_mult(ray->dir, ray->t), lray.pos), ray->pos)); lray.invdir = get_inv_vect(&lray.dir); if (find_closest(scene, &lray) && ray->closest == lray.closest && near_enough(ray, &lray)) { set_params(&ph, &lray, ray); ph.camera = scene->camera; ph.light = (t_light *)current->content; phong(&ph); } current = current->next; } set_color_max(&ph); return (*color); }
//! generate normal vector std::vector<Real> normal_vector(size_t size) const { std::vector<Real> v(size); for(size_t idx = 0; idx < size; idx++) { v[idx] = get_normal(); } return v; }
/* Compute the reflection of a vector on an object. * * the_object: The object to reflect off of. * position: The position hit. * direction: The direction of the vector to be reflected. * * Returns: the reflection of direction on the object at position. */ float* reflection_vector(object *the_object, float *position, float *direction) { float *reflection = (float*)malloc(sizeof(float)*3); float *normal = get_normal(the_object, position); v_scale(normal, -2*v_dot(direction, normal), reflection); v_add(reflection, direction, reflection); v_unit(reflection, reflection); return reflection; }
void get_reflected_ray(t_ray* ray, t_object* obj, t_ray* new_ray) { new_ray->distance = 20000; mult_vector(&ray->dest, &new_ray->origin, ray->distance); add_vector(&new_ray->origin, &ray->origin, &new_ray->origin); get_normal(obj, &new_ray->origin, &new_ray->dest); mult_vector(&new_ray->dest, &new_ray->dest, dot_vector(&ray->dest, &new_ray->dest)); mult_vector(&new_ray->dest, &new_ray->dest, 2); sub_vector(&ray->dest, &new_ray->dest, &new_ray->dest); }
void place_object(int i) { float obj_normal[3] = {0,1,0}; /* set object's (at least initial) elevation */ if (full_objects[i].type !=7 ) get_normal(full_objects[i].area[0], full_objects[i].area[1], obj_normal); full_objects[i].rot[1] = RADS_TO_DEGS*atan(obj_normal[2]/obj_normal[1]); full_objects[i].rot[2] = -RADS_TO_DEGS*atan(obj_normal[0]/obj_normal[1]); /* set object's (at least initial) pitch and roll on the terrain */ full_objects[i].pos[1] = get_elevation(full_objects[i].pos[0], full_objects[i].pos[2]); }
void calculate_normal(vec3_t normal, int edge, size_t x, size_t y, size_t z, float offset, scan_data *data) { vec3 v1; vec3 v2; get_normal((vec3_t) &v1, (x + cube_vertices[cube_edge_connections[edge][0]][0]), (y + cube_vertices[cube_edge_connections[edge][0]][1]), (z + cube_vertices[cube_edge_connections[edge][0]][2]), data); get_normal((vec3_t) &v2, (x + cube_vertices[cube_edge_connections[edge][1]][0]), (y + cube_vertices[cube_edge_connections[edge][1]][1]), (z + cube_vertices[cube_edge_connections[edge][1]][2]), data); normal[0] = v1[0] + (v2[0] - v1[0]) * offset; normal[1] = v1[1] + (v2[1] - v1[1]) * offset; normal[2] = v1[2] + (v2[2] - v1[2]) * offset; vec3_normalize(normal, normal); }
bool triangle3<T>::get_intersection_of__plane_with_line(const vec3<T>& linePoint, const vec3<T>& lineVect, vec3<T>& outIntersection) const { const vec3<T> normal = normalized(get_normal()); T t2 = dot(normal,lineVect); if (is_zero(t2)) return false; T d = dot(pointA,normal); T t = -(dot(normal,linePoint) - d) / t2; outIntersection = linePoint + (lineVect * t); return true; }
void player_handle_movement(Player *p, Wall *walls, float dt) { // Calculate angle based on where facing p->angle = atan2((p->face.y - p->exact_pos.y),(p->face.x - p->exact_pos.x)); // apply friction p->vel.x *= p->friction; p->vel.y *= p->friction; // apply acceleration p->vel.x += p->x_input * p->acc; p->vel.y -= p->y_input * p->acc; // update position fvector new_pos; new_pos.x = p->exact_pos.x + p->vel.x*dt; new_pos.y = p->exact_pos.y + p->vel.y*dt; // check for collisions with walls int i; for (i=0; i < WALL_MAX; i++) { if (walls[i].ex) { Intersection sect; fvector evec1, evec2, wvec, norm, snorm; evec1 = f_vector(walls[i].end1.x, walls[i].end1.y); evec2 = f_vector(walls[i].end2.x, walls[i].end2.y); wvec = vector_subtract(evec1, evec2); norm = get_normal(wvec); if (dot_product_f_vectors(norm, p->vel) > 0) norm = scale_f_vector(norm, -1); snorm = scale_f_vector(norm, 20); sect = intersect_line_segments(p->exact_pos, new_pos, translate_f_vector(evec1, snorm), translate_f_vector(evec2, snorm)); if (sect.intersects) { new_pos = translate_f_vector(sect.point, norm); } } } p->exact_pos=new_pos; // handle collision with screen edges player_check_bounds(p); }
void color_cylinder(t_ray* ray, t_vector* inter, t_object* obj, t_color* clr) { t_vector normal; double angle; t_vector light; get_normal(obj, inter, &normal, ray); sub_vector(NULL, &ray->dest, &light); angle = dot_vector(&normal, &light); if (angle < 0.0) angle = 0.0; clr->r = obj->material.diffuse.r * AMBIANT_RED * angle; clr->g = obj->material.diffuse.g * AMBIANT_GREEN * angle; clr->b = obj->material.diffuse.b * AMBIANT_BLUE * angle; }
u_int calc_light(t_mlx *mlx, t_xyz *spot) { t_xyz p; t_xyz light; t_xyz normal; double cos_a; u_int new_color; p = (t_xyz){mlx->eye.x + mlx->k * mlx->vector.x, mlx->eye.y + mlx->k * mlx->vector.y, mlx->eye.z + mlx->k * mlx->vector.z}; light = (t_xyz){spot->x - p.x, spot->y - p.y, spot->z - p.z}; new_color = mlx->cur_obj->color; get_normal(&normal, &p, mlx->cur_obj); cos_a = (normal.x * light.x + normal.y * light.y + normal.z * light.z) / (norme_vector(&normal) * norme_vector(&light)); new_color = (cos_a >= 0 && cos_a <= 1) ? mult_color(mlx->cur_obj->color, cos_a) : 0; return (new_color); }
static void set_refract_ray_prim(t_env *e, t_env *refract) { t_vector n; refract->ray.loc = vadd(e->ray.loc, vmult(e->ray.dir, e->t)); n = get_normal(e, refract->ray.loc); if (refract->flags & RAY_INSIDE) { n = vunit(vsub((t_vector){0.0, 0.0, 0.0}, n)); if (refract_prim(e, refract, n)) refract->flags &= ~RAY_INSIDE; else set_reflect_ray(e, refract); } else { if (refract_prim(e, refract, n)) refract->flags |= RAY_INSIDE; else set_reflect_ray(e, refract); } }
algebra::Vector3Ds get_normals(const Ints &faces, const algebra::Vector3Ds &vertices) { IMP_INTERNAL_CHECK(faces.size() % 3 == 0, "Not triangles"); IMP_INTERNAL_CHECK(faces.size() > 0, "No faces"); Ints count(vertices.size()); algebra::Vector3Ds sum(vertices.size(), algebra::get_zero_vector_d<3>()); for (unsigned int i = 0; i < faces.size() / 3; ++i) { algebra::Vector3D n = get_normal(faces.begin() + 3 * i, faces.begin() + 3 * i + 3, vertices); IMP_INTERNAL_CHECK(!IMP::isnan(n[0]), "Nan found"); for (unsigned int j = 0; j < 3; ++j) { int v = faces[3 * i + j]; sum[v] += n; count[v] += 1; } } for (unsigned int i = 0; i < count.size(); ++i) { sum[i] /= count[i]; IMP_INTERNAL_CHECK(!IMP::isnan(sum[i][0]), "Nan found at end:" << count[i] << " on " << i); } return sum; }
void init_refraction(t_ray** rays, t_vector* normal, t_object* obj, t_vector* tmp) { (*rays[1]).distance = 20000; mult_vector(&(*rays[0]).dest, &(*rays[1]).origin, (*rays[0]).distance); add_vector(&(*rays[1]).origin, &(*rays[0]).origin, &(*rays[1]).origin); get_normal(obj, &(*rays[1]).origin, normal, rays[0]); sub_vector(NULL, &(*rays[0]).dest, tmp); if ((*rays[0]).in_obj == 0) { if (obj->obj_type != E_PLANE) (*rays[1]).in_obj = 1; else (*rays[1]).in_obj = 0; (*rays[1]).refract = obj->material.refract; } else { sub_vector(NULL, normal, normal); (*rays[1]).in_obj = 0; (*rays[1]).refract = 1.0; } }
bool BatchGeom::add_normals(){ if (m_indices == NULL) return false; if (m_primitive_type != PRIM_TRIANGLES) return false; if (!find_attribute(ATT_NORMAL) && !insert_attribute(ATT_NORMAL, 3) ) return false; for(unsigned int i=0; i<m_num_indices; ++i) { get_normal_by_index( i ) = noVec3( 0.0f, 0.0f, 0.0f ); } for(unsigned int i=0; i<m_num_indices; i+=3) { noVec3 v1 = get_vertex_by_index( i+0 ); noVec3 v2 = get_vertex_by_index( i+1 ); noVec3 v3 = get_vertex_by_index( i+2 ); noVec3 normal = ( v2-v1).Cross(v3-v1 ).NormalizeCopy(); get_normal_by_index( i+0 ) += normal; get_normal_by_index( i+1 ) += normal; get_normal_by_index( i+2 ) += normal; } for(unsigned int i=0; i<m_num_vertices; ++i) { get_normal( i ).Normalize(); } return true; }
int texture(t_vector3 eye, t_vector3 cam, t_best best) { unsigned int color; int c; double v; double u; double pos; translate(&eye, best.obj.p, 1); rot_inv(&eye, best.obj.r); rot_inv(&cam, best.obj.r); scale(&(cam), best.obj.s); best.normal = unitaire(get_normal(cam, eye, best)); u = (int)(best.obj.tex.w * (0.5 + atan2(best.normal.z, best.normal.x) / (2 * M_PI))); v = (int)(best.obj.tex.h * (0.5 - asin(best.normal.y) / M_PI)); pos = 4 * u + 4 * v * best.obj.tex.w; c = (int)pos; color = 0; color += best.obj.tex.texture.data[c++] << 8; color += best.obj.tex.texture.data[c++] << 16; color += best.obj.tex.texture.data[c++] << 24; return (color); }
void draw_cube() { // draws a cube Point normal; glMatrixMode(GL_MODELVIEW); glPushMatrix(); if (!INIT) { glLoadMatrixd(cube_matrix); } if (ROTATE_CUBE != 0) { GLdouble angle = (GLdouble) 5. * ROTATE_CUBE; glRotated(angle, 0, 0, 1); ROTATE_CUBE = 0; } // shape drawing // front glBegin(GL_POLYGON); // Ugly coding inc'... Point a = {1,1,1,1}; Point b = {1,1,-1,1}; Point c = {1,-1,-1,1}; Point d = {1,-1,1,1}; switch (MODE) { case 1: get_normal(a,b,c, normal); glNormal3dv(normal); break; } glVertex3d(1,1,1); glVertex3d(1,1,-1); glVertex3d(1,-1,-1); glVertex3d(1,-1,1); glEnd(); // right glBegin(GL_POLYGON); Point e = {1,1,1,1}; Point f = {-1,1,1,1}; Point g = {-1,1,-1,1}; Point h = {1,1,-1,1}; switch (MODE) { case 1: get_normal(a,b,c, normal); glNormal3dv(normal); break; } glVertex3d(1,1,1); glVertex3d(-1,1,1); glVertex3d(-1,1,-1); glVertex3d(1,1,-1); glEnd(); // back glBegin(GL_POLYGON); Point i = {-1,1,1,1}; Point j = {-1,1,-1,1}; Point k = {-1,-1,-1,1}; Point l = {-1,-1,1,1}; switch (MODE) { case 1: get_normal(a,b,c, normal); glNormal3dv(normal); break; } glVertex3d(-1,1,1); glVertex3d(-1,1,-1); glVertex3d(-1,-1,-1); glVertex3d(-1,-1,1); glEnd(); // left glBegin(GL_POLYGON); Point m = {1,1,1,1}; Point n = {1,1,-1,1}; Point o = {1,-1,-1,1}; Point p = {1,-1,1,1}; switch (MODE) { case 1: get_normal(a,b,c, normal); glNormal3dv(normal); break; } glVertex3d(1,1,1); glVertex3d(1,1,-1); glVertex3d(1,-1,-1); glVertex3d(1,-1,1); glEnd(); // bottom glBegin(GL_POLYGON); Point q = {1,1,-1,1}; Point r = {1,-1,-1,1}; Point s = {-1,-1,-1,1}; Point t = {-1,1,-1,1}; switch (MODE) { case 1: get_normal(a,b,c, normal); glNormal3dv(normal); break; } glVertex3d(1,1,-1); glVertex3d(1,-1,-1); glVertex3d(-1,-1,-1); glVertex3d(-1,1,-1); glEnd(); // top glBegin(GL_POLYGON); Point u = {1,1,1,1}; Point v = {1,-1,1,1}; Point w = {-1,-1,1,1}; Point x = {-1,1,1,1}; switch (MODE) { case 1: get_normal(a,b,c, normal); glNormal3dv(normal); break; } glVertex3d(1,1,1); glVertex3d(1,-1,1); glVertex3d(-1,-1,1); glVertex3d(-1,1,1); glEnd(); glGetDoublev(GL_MODELVIEW_MATRIX, cube_matrix); glPopMatrix(); }
void draw_pyramid() { // draws a pyramid Point normal; glMatrixMode(GL_MODELVIEW); glPushMatrix(); // if first time we draw, translate, else load anterior // transfo matrix if (INIT) { glTranslatef(0, 0, 2); } else { glLoadMatrixd(pyramid_matrix); } // if rotation, rotate if (ROTATE_PYRAMID != 0) { GLdouble angle = (GLdouble) 5 * ROTATE_PYRAMID; glRotated(angle, 0, 0, 1); ROTATE_PYRAMID = 0; } // bottom glBegin(GL_POLYGON); Point a = {1,1,0,1}; Point b = {-1,1,0,1}; Point c = {-1,-1,0,1}; Point d = {1,-1,0,1}; switch (MODE) { case 1: get_normal(a,b,c, normal); glNormal3dv(normal); break; } glVertex3d(1,1,0); glVertex3d(-1,1,0); glVertex3d(-1,-1,0); glVertex3d(1,-1,0); glEnd(); // front glBegin(GL_POLYGON); Point e = {1,1,0,1}; Point f = {1,-1,0,1}; Point g = {0,0,1,1}; switch (MODE) { case 1: get_normal(a,b,c, normal); glNormal3dv(normal); break; } glVertex3d(1,1,0); glVertex3d(1,-1,0); glVertex3d(0,0,1); glEnd(); // right glBegin(GL_POLYGON); Point h = {1,1,0,1}; Point i = {-1,1,0,1}; Point j = {0,0,1,1}; switch (MODE) { case 1: get_normal(a,b,c, normal); glNormal3dv(normal); break; } glVertex3d(1,1,0); glVertex3d(-1,1,0); glVertex3d(0,0,1); glEnd(); // back glBegin(GL_POLYGON); Point k = {-1,1,0,1}; Point l = {-1,-1,0,1}; Point m = {0,0,1,1}; switch (MODE) { case 1: get_normal(a,b,c, normal); glNormal3dv(normal); break; } glVertex3d(-1,1,0); glVertex3d(-1,-1,0); glVertex3d(0,0,1); glEnd(); // left glBegin(GL_POLYGON); Point n = {-1,-1,0,1}; Point o = {1,-1,0,1}; Point p = {0,0,1,1}; switch (MODE) { case 1: get_normal(a,b,c, normal); glNormal3dv(normal); break; } glVertex3d(-1,-1,0); glVertex3d(1,-1,0); glVertex3d(0,0,1); glEnd(); // save current transfo state glGetDoublev(GL_MODELVIEW_MATRIX, pyramid_matrix); glPopMatrix(); }
Vector3 Plane::get_any_point() const { return get_normal() * d; }
Point<float> GMWMI_finder::normal (const Point<float>& p) const { Interp interp (interp_template); return get_normal (p, interp); }
ParticleList& BeamEmitter::obliqueEmit(Scalar t, Scalar dt) { Vector2 xMKS; for (int j=0; j < 4*(j2 - j1) + 2; j += 2){ int index = j/2; int jl = points[j]; int kl = points[j+1]; int jh = points[j+2]; int kh = points[j+3]; if (jh == jl && kh == kl) continue; // if this is a duplicate point, get next Vector2 p1 = fields->getMKS(jl, kl); // note these are local to this segment Vector2 p2 = fields->getMKS(jh, kh); Scalar localRate = emissionRate*dt*get_time_value(t)*area[index]/totalArea; oblExtra[index] += localRate; if (oblExtra[index] < 1) continue; // not enough to emit in this cell Scalar del_t = dt/localRate; while (oblExtra[index] >= 1) { oblExtra[index] -= 1; if (kl == kh || !rweight) xMKS = p1 + frand()*(p2 - p1); else { Scalar r_min = p1.e2(); Scalar r_max = p2.e2(); xMKS = Vector2(0.5*(p1.e1() + p2.e1()), sqrt(r_min*r_min + (r_max*r_max - r_min*r_min)*frand())); } Vector2 x = fields->getGridCoords(xMKS); if (kl == kh) { // horizontal // x += deltaHorizontal; // perturb particles off boundary normal = Vector3(0, 1, 0)*get_normal(); } else if (k2 > k1) { // up and right // x -= deltaVertical; normal = Vector3(-1, 0, 0)*get_normal(); } else { // down and right // x += deltaVertical; normal = Vector3(1, 0, 0)*get_normal(); } Vector3 u; if (thetaDot.e3()){ // only correct if r*thetaDot << vz // thetaDot is yDot for ZXgeometry Vector3 v = maxwellian->get_V(normal); if (rweight) v+=xMKS.e2()*thetaDot; u = v/sqrt(1-v*v*iSPEED_OF_LIGHT_SQ); } else u = maxwellian->get_U(normal); x += delta; Particle* p = new Particle(x, u, species, np2c); Boundary* bPtr = initialPush(del_t*oblExtra[index], dt, *p); if (!bPtr) particleList.add(p); } } return particleList; }
int convert_triangle (struct surface *srf, struct face *f) { int j, k, n_e, atm, comp, shape; int orn; int arc_orn[3]; long ofn; long arc_number[3]; double radius, circumference; double tri_center[3], tri_normal[3]; char message[MAXLINE]; char shape_string[24]; struct vertex *tri_vtx[3]; struct arc *arc_ptrs[3]; struct arc *a; struct edge *ed; struct cycle *cyc, *fcyc; struct face *fac; struct variety *vty; struct phnvtx *pv; struct phnedg *pe; struct phntri *pt; struct phntri **head_phntri; struct phntri **tail_phntri; for (k = 0; k < 3; k++) tri_normal[k] = 0.0; if (f -> converted) return(1); pt = allocate_phntri (); if (pt == NULL) { print_counts(); set_error1 ("(convert_triangle): memory allocation failure"); print_counts(); return (0); } comp = f -> comp; ofn = f -> ofn; if (ofn <= 0) { sprintf(message, "convert_triangle: ofn = %8ld", ofn); set_error1(message); return(0); } cyc = f -> first_cycle; if (cyc == NULL) { inform("convert_triangle: no cycles"); return (0); } n_e = 0; for (ed = cyc -> first_edge; ed != NULL; ed = ed -> next) { n_e++; } if (n_e > 3) { sprintf (message, "(convert_triangle): face with %d sides", n_e); set_error1 (message); sprintf (message, "ofn = %ld, lfn = %ld", f -> ofn, f -> lfn); set_error2 (message); return (0); } n_e = 0; for (ed = cyc -> first_edge; ed != NULL; ed = ed -> next) { a = ed -> arcptr; if (a == NULL) { set_error1 ("(convert_triangle): null arc"); return (0); } if (n_e > 2) { sprintf (message, "(convert_triangle): face with %d sides", n_e); set_error1 (message); sprintf (message, "ofn = %ld, lfn = %ld", f -> ofn, f -> lfn); set_error2 (message); return (0); } orn = ed -> orn; arc_orn[n_e] = orn; arc_number[n_e] = a -> number; arc_ptrs[n_e] = a; tri_vtx[n_e] = a -> vtx[orn]; if (tri_vtx[n_e] == NULL) { set_error1 ("(convert_triangle): null vertex"); return (0); } n_e++; } fac = *(srf -> face_handles + ofn - 1); if (fac == NULL) { inform("convert_triangle: face_handles array has null face pointer"); return (0); } fcyc = fac -> first_cycle; circumference = circum (fcyc); shape = fac -> shape; vty = fac -> vty; if (vty == NULL) { inform("convert_triangle: variety pointer is null"); return (0); } radius = vty -> radii[0]; get_tri_center (tri_vtx, tri_center, n_e); atm = point_choice (srf, tri_center, vty, shape); if (error()) { inform("convert_triangle: point_choice fails"); return(0); } if (n_e < 3) { sprintf (message, "atom %d triangle has only %d sides, %hd cycles, %hd arcs", atm, n_e, fac -> n_cycle, fac -> n_arc); set_error1 (message); if (shape == CONVEX) strcpy (shape_string, "face shape = convex"); else if (shape == SADDLE) strcpy (shape_string, "face shape = saddle"); else if (shape == CONCAVE) strcpy (shape_string, "face shape = concave"); else if (shape == FLAT) strcpy (shape_string, "face shape = flat"); else if (shape == CYLINDRICAL) strcpy (shape_string, "face shape = cylindrical"); sprintf (message, "%s, omega = %12.6f, circumference = %12.6f", shape_string, fac -> area / (radius * radius), circumference); set_error2 (message); return (0); } if(!get_normal (tri_vtx, tri_normal)) { informd2("warning: degenerate triangle, no normal computed"); } /* store the data in the new structure */ for (j = 0; j < 3; j++) { pt -> axis[j] = tri_normal[j]; pt -> edg[j] = arc_ptrs[j] -> ped; pt -> orns[j] = arc_orn[j]; } pt -> comp = (short) comp; pt -> atm = (short) atm; pt -> shape = (short) shape; /* property of each of three vertices */ for (j = 0; j < 3; j++) { pe = pt -> edg[j]; orn = pt -> orns[j]; pv = pe -> pvt[orn]; pv -> degree++; for (k = 0; k < 3; k++) pv -> outward[k] += tri_normal[k]; } f -> converted = 1; head_phntri = srf -> heads + atm - 1; tail_phntri = srf -> tails + atm - 1; if (*head_phntri == (struct phntri *) NULL) *head_phntri = pt; else (*tail_phntri) -> next = pt; *tail_phntri = pt; srf -> n_phntri++; return(1); }
bool point_triangle_collision(const Vec3d& x0, const Vec3d& xnew0, unsigned int index0, const Vec3d& x1, const Vec3d& xnew1, unsigned int index1, const Vec3d& x2, const Vec3d& xnew2, unsigned int index2, const Vec3d& x3, const Vec3d& xnew3, unsigned int index3, double& bary1, double& bary2, double& bary3, Vec3d& normal, double& t, double& relative_normal_displacement, bool verbose ) { assert( index1 < index2 && index2 < index3 ); const int segment_tetrahedron_test = 2; double p0[4] = { x0[0], x0[1], x0[2], 0.0 }; double pnew0[4] = { xnew0[0], xnew0[1], xnew0[2], 1.0 }; double p1[4] = { x1[0], x1[1], x1[2], 0.0 }; double pnew1[4] = { xnew1[0], xnew1[1], xnew1[2], 1.0 }; double p2[4] = { x2[0], x2[1], x2[2], 0.0 }; double pnew2[4] = { xnew2[0], xnew2[1], xnew2[2], 1.0 }; double p3[4] = { x3[0], x3[1], x3[2], 0.0 }; double pnew3[4] = { xnew3[0], xnew3[1], xnew3[2], 1.0 }; bool collision=false; double bary[6]; if ( simplex_intersection4d( segment_tetrahedron_test, p0, pnew0, p1, p2, p3, pnew3, &bary[0], &bary[1], &bary[2], &bary[3], &bary[4], &bary[5] ) ) { collision=true; bary1=0; bary2=0; bary3=1; t=bary[1]; normal=get_normal(x2-x1, x3-x1); relative_normal_displacement=dot(normal, (xnew0-x0)-(xnew3-x3)); if ( verbose ) { std::cout << "segment_tetrahedron_test positive with these inputs: " << std::endl; std::cout.precision(20); out4d(p0); out4d(pnew0); out4d(p1); out4d(p2); out4d(p3); out4d(pnew3); } } if ( simplex_intersection4d( segment_tetrahedron_test, p0, pnew0, p1, p2, pnew2, pnew3, &bary[0], &bary[1], &bary[2], &bary[3], &bary[4], &bary[5] ) ) { if(!collision || bary[1]<t) { collision=true; bary1=0; bary2=(bary[4]+1e-300)/(bary[4]+bary[5]+2e-300); // guard against zero/zero bary3=1-bary2; t=bary[1]; normal=get_normal(x2-x1, xnew3-xnew2); relative_normal_displacement=dot(normal, (xnew0-x0)-(xnew2-x2)); if ( verbose ) { std::cout << "segment_tetrahedron_test positive with these inputs: " << std::endl; std::cout.precision(20); out4d(p0); out4d(pnew0); out4d(p1); out4d(p2); out4d(pnew2); out4d(pnew3); } } } if ( simplex_intersection4d( segment_tetrahedron_test, p0, pnew0, p1, pnew1, pnew2, pnew3, &bary[0], &bary[1], &bary[2], &bary[3], &bary[4], &bary[5] ) ) { if(!collision || bary[1]<t) { collision=true; bary1=(bary[3]+1e-300)/(bary[3]+bary[4]+bary[5]+3e-300); // guard against zero/zero bary2=(bary[4]+1e-300)/(bary[3]+bary[4]+bary[5]+3e-300); // guard against zero/zero bary3=1-bary1-bary2; t=bary[1]; normal=get_normal(xnew2-xnew1, xnew3-xnew1); relative_normal_displacement=dot(normal, (xnew0-x0)-(xnew1-x1)); if ( verbose ) { std::cout << "segment_tetrahedron_test positive with these inputs: " << std::endl; std::cout.precision(20); out4d(p0); out4d(pnew0); out4d(p1); out4d(pnew1); out4d(pnew2); out4d(pnew3); } } } if ( collision ) { Vec3d dx0 = xnew0 - x0; Vec3d dx1 = xnew1 - x1; Vec3d dx2 = xnew2 - x2; Vec3d dx3 = xnew3 - x3; relative_normal_displacement = dot( normal, dx0 - bary1*dx1 - bary2*dx2 - bary3*dx3 ); } return collision; }
bool segment_segment_collision(const Vec3d& x0, const Vec3d& xnew0, unsigned int index0, const Vec3d& x1, const Vec3d& xnew1, unsigned int index1, const Vec3d& x2, const Vec3d& xnew2, unsigned int index2, const Vec3d& x3, const Vec3d& xnew3, unsigned int index3, double& bary0, double& bary2, Vec3d& normal, double& t, double& relative_normal_displacement, bool verbose ) { assert( index0 < index1 && index2 < index3 ); const int triangle_triangle_test = 3; double p0[4] = { x0[0], x0[1], x0[2], 0.0 }; double pnew0[4] = { xnew0[0], xnew0[1], xnew0[2], 1.0 }; double p1[4] = { x1[0], x1[1], x1[2], 0.0 }; double pnew1[4] = { xnew1[0], xnew1[1], xnew1[2], 1.0 }; double p2[4] = { x2[0], x2[1], x2[2], 0.0 }; double pnew2[4] = { xnew2[0], xnew2[1], xnew2[2], 1.0 }; double p3[4] = { x3[0], x3[1], x3[2], 0.0 }; double pnew3[4] = { xnew3[0], xnew3[1], xnew3[2], 1.0 }; bool collision=false; double bary[6]; if ( simplex_intersection4d( triangle_triangle_test, p0, p1, pnew1, p2, p3, pnew3, &bary[0], &bary[1], &bary[2], &bary[3], &bary[4], &bary[5] ) ) { collision=true; bary0=0; bary2=0; t=bary[2]; normal=get_normal(x1-x0, x3-x2); relative_normal_displacement=dot(normal, (xnew1-x1)-(xnew3-x3)); if ( verbose ) { std::cout << "triangle_triangle_test positive with these inputs: " << std::endl; output_4d(p0); output_4d(p1); output_4d(pnew1); output_4d(p2); output_4d(p3); output_4d(pnew3); std::cout << "barycentric coords: " << std::endl; for ( unsigned int i = 0; i < 6; ++i ) { std::cout << bary[i] << " " << std::endl; } g_verbose = true; simplex_intersection4d( triangle_triangle_test, p0, p1, pnew1, p2, p3, pnew3, &bary[0], &bary[1], &bary[2], &bary[3], &bary[4], &bary[5] ); g_verbose = false; assert(0); } } if ( simplex_intersection4d( triangle_triangle_test, p0, pnew0, pnew1, p2, p3, pnew3, &bary[0], &bary[1], &bary[2], &bary[3], &bary[4], &bary[5] ) ) { if(!collision || bary[5]<t) { collision=true; bary0=(bary[1]+1e-300)/(bary[1]+bary[2]+2e-300); // guard against zero/zero bary2=0; t=bary[5]; normal=get_normal(xnew1-xnew0, x3-x2); relative_normal_displacement=dot(normal, (xnew0-x0)-(xnew3-x3)); if ( verbose ) { std::cout << "triangle_triangle_test positive with these inputs: " << std::endl; output_4d(p0); output_4d(pnew0); output_4d(pnew1); output_4d(p2); output_4d(p3); output_4d(pnew3); } } } if ( simplex_intersection4d( triangle_triangle_test, p0, p1, pnew1, p2, pnew2, pnew3, &bary[0], &bary[1], &bary[2], &bary[3], &bary[4], &bary[5] ) ) { if(!collision || bary[2]<t){ collision=true; bary0=0; bary2=(bary[4]+1e-300)/(bary[4]+bary[5]+2e-300); // guard against zero/zero t=bary[2]; normal=get_normal(x1-x0, xnew3-xnew2); relative_normal_displacement=dot(normal, (xnew1-x1)-(xnew2-x2)); if ( verbose ) { std::cout << "triangle_triangle_test positive with these inputs: " << std::endl; output_4d(p0); output_4d(p1); output_4d(pnew1); output_4d(p2); output_4d(pnew2); output_4d(pnew3); } } } if ( simplex_intersection4d( triangle_triangle_test, p0, pnew0, pnew1, p2, pnew2, pnew3, &bary[0], &bary[1], &bary[2], &bary[3], &bary[4], &bary[5] ) ) { if(!collision || 1-bary[0]<t){ collision=true; bary0=(bary[1]+1e-300)/(bary[1]+bary[2]+2e-300); // guard against zero/zero bary2=(bary[4]+1e-300)/(bary[4]+bary[5]+2e-300); // guard against zero/zero t=1-bary[0]; normal=get_normal(xnew1-xnew0, xnew3-xnew2); relative_normal_displacement=dot(normal, (xnew0-x0)-(xnew2-x2)); if ( verbose ) { std::cout << "triangle_triangle_test positive with these inputs: " << std::endl; output_4d(p0); output_4d(pnew0); output_4d(pnew1); output_4d(p2); output_4d(pnew2); output_4d(pnew3); } } } if ( collision ) { Vec3d dx0 = xnew0 - x0; Vec3d dx1 = xnew1 - x1; Vec3d dx2 = xnew2 - x2; Vec3d dx3 = xnew3 - x3; relative_normal_displacement = dot( normal, bary0*dx0 + (1.0-bary0)*dx1 - bary2*dx2 - (1.0-bary2)*dx3 ); } return collision; }