Ejemplo n.º 1
0
Mat* create_look_at_mat(Vec* cam_pos, Vec* targ_pos, Vec* up) {
    Mat* p = create_translation_mat(-cam_pos->x, -cam_pos->y, -cam_pos->z);
    Vec* d = vec_minus_vec(targ_pos, cam_pos);
    Vec* f = normalize_vec(d);
    
    Vec* c1 = cross_vec(f, up);
    Vec* r = normalize_vec(c1);

    Vec* c2 = cross_vec(r, f);
    Vec* u = normalize_vec(c2);

    Mat* ori = identity_mat();
    ori->m[0] = r->x;
    ori->m[4] = r->y;
    ori->m[8] = r->z;
    ori->m[1] = u->x;
    ori->m[5] = u->y;
    ori->m[9] = u->z;
    ori->m[2] = -f->x;
    ori->m[6] = -f->y;
    ori->m[10] = -f->z;

    Mat* ret = mat_times_mat(ori, p);

    delete_mat(p);
    delete_mat(ori);
    delete_vec(d);
    delete_vec(f);
    delete_vec(r);
    delete_vec(u);
    delete_vec(c1);
    delete_vec(c2);

    return ret;
}
Ejemplo n.º 2
0
/**
 * Determine if one segment intersects another.
 *
 * @param _s1 the threshold edge
 * @param _s2 the segment
 * @param _i1 the possible intersection point
 * @param _i2 the possible intersection point
 * @return 0 if the segments do not intersect
 *         1 if one segment intersects another at precisely one point
 *         2 if one segment overlaps another, in which case there are two intersection points.
 * @throw CException should any of the following occur:
 *        1. zero v.y.
  */
unsigned short CThreshold::seg_intersection(seg& _s1, seg& _s2, pt& _i1, pt& _i2 ) {
	unsigned short intersect = 0;
	vec u, v, w, w2;
    double d, du, dv;
    double t, t0, t1;
    double si, ti;

    do {
    	init_vec(_s1.p1, _s1.p2, u);
		init_vec(_s2.p1, _s2.p2, v);
		init_vec(_s2.p1, _s1.p1, w);

    	d = cross_vec(u, v);

        if (fabs(d) < PARALLELISM_TOLERANCE) {
            // segments are parallel
        	if (cross_vec(u, w) != 0 || cross_vec(v, w) != 0) {
                // not colinear
        		break;
    	    }

        	// they are colinear or degenerate
    	    // check if they are degenerate points
    	    du = dot_vec(u, u);
    	    dv = dot_vec(v, v);

    	    if (0 == du && 0 == dv) {
    	    	// both segments are points
    	    	if (pts_equal(_s1.p1, _s2.p1)) {
    	    		// the same point
    	    		intersect = 1;
    	    		init_pt(_i1, _s1.p1);
    	        }

    	        break;
    	    }

    	    if (0 == du) {
    	    	// s1 is a single point
    	    	if (pt_within_seg(_s2, _s1.p1)) {
    	    		// is within s2
    	    		intersect = 1;
    	    		init_pt(_i1, _s1.p1);
    	    	}

    	        break;
    	    }

    	    if (0 == dv) {
    	    	// s2 a single point
    	    	if (pt_within_seg(_s1, _s2.p1)) {
    	    		// is within s1
    	    		intersect = 1;
    	    		init_pt(_i1, _s2.p1);
    	        }

    	        break;
    	    }

    	    // colinear segments - get overlap (or not)
    	    init_vec(_s2.p1, _s1.p2, w2);

    	    if (0 != v.x) {
    	    	t0 = w.x/v.x;
    	        t1 = w2.x/v.x;
    	    }
    	    else {
    	    	if (0.0 == v.y) {
    	    		throw CException("Error! Zero v.y.");
    	    	}

    	        t0 = w.y/v.y;
    	        t1 = w2.y/v.y;
    	    }

            // must have t0 smaller than t1
    	    if (t0 > t1) {
    	        // swap if not
    	    	t  = t0;
    	        t0 = t1;
    	        t1 = t;
    	    }

    	    if (t0 > 1 || t1 < 0) {
    	        break; // no overlap
    	    }

    	    t0 = t0 < 0 ? 0 : t0; // clip to min 0
    	    t1 = t1 > 1 ? 1 : t1; // clip to max 1

    	    if (t0 == t1) {
    	    	// intersection is a pt
    	    	intersect = 1;
    	    	_i1.x = _s2.p1.x + (t0*v.x);
    	    	_i1.y = _s2.p1.y + (t0*v.y);
    	    	break;
    	    }

    	    // they overlap in a valid subseg
    	    intersect = 2;
    	    _i1.x = _s2.p1.x + (t0*v.x);
    	    _i1.y = _s2.p1.y + (t0*v.y);
    	    _i2.x = _s2.p1.x + (t1*v.x);
    	    _i2.y = _s2.p1.y + (t1*v.y);
    	    break;
        } // end of <if (fabs(d) < PARALLELISM_TOLERANCE)> clause

        // the segs are skew and may intersect in a pt
        // get the intersect parameter for s1
        si = cross_vec(v, w)/d;
        if (si < 0 || si > 1) {
        	// no intersect with s1
        	break;
        }

        // get the intersect parameter for S2
        ti = cross_vec(u, w)/d;
        if (ti < 0 || ti > 1) {
        	// no intersect with s2
        	break;
        }

        intersect = 1;
        _i1.x = _s1.p1.x + (si*u.x);
        _i1.y = _s1.p1.y + (si*u.y);

    } while (0);

    return intersect;
}