Osaisikohan joku sanoa mikä menee metsään kun yritän piirtää viivoja joiden toinen pää on kameran takana.
Tulee tämmöistä:
http://www.elektroniikkafoorumi.com/images/VIIVAT.png
Vihreät pisteet näyttää mis viivojen pitäis mennä.
void drawLines(SDL_Surface * dst, const std::list<LINE3D> & lines, const CAMERA & cam, const CAM_TRIG_VALUES & cam_sincos, int res_x, int res_y, double view_tan_x, double view_tan_y) { std::list<LINE3D>::const_iterator line_it = lines.begin(); while(line_it != lines.end()) { COORD3D r1 = transformToCameraCoordinates(line_it->p1, cam_sincos); COORD3D r2 = transformToCameraCoordinates(line_it->p2, cam_sincos); //debug COORD3D d1 = r1, d2 = r2; //debug end //ainakin toinen kameran etupuolella if(r1.z > 0.0 || r2.z > 0.0) { // calculateScreenCoordinates sekoo negatiivisista Z kordinaatteja // joten pistetään XY tasosta poikki if(r1.z < 0.0) { r1 = findIntersectionXY(*line_it); } if(r2.z < 0.0) { r2 = findIntersectionXY(*line_it); } drawLine(dst, calculateScreenCoordinates(r1, res_x, res_y, view_tan_x, view_tan_y), calculateScreenCoordinates(r2, res_x, res_y, view_tan_x, view_tan_y)); //debug std::list<COORD3D> points; //red dots to r1 -> r2 mapDotLine(points, r1, r2, 100); while(!points.empty()) { if(points.back().z > 0.0) drawDot(dst, calculateScreenCoordinates(points.back(), res_x, res_y, view_tan_x, view_tan_y), SDL_MapRGB(dst->format, 255, 0, 0)); points.pop_back(); } // green dots d1 -> d2 mapDotLine(points, d1, d2, 100); while(!points.empty()) { if(points.back().z > 0.0) drawDot(dst, calculateScreenCoordinates(points.back(), res_x, res_y, view_tan_x, view_tan_y), SDL_MapRGB(dst->format, 0, 255, 0)); points.pop_back(); } //debug end } line_it++; } }
struct COORD3D { double x, y, z; }; struct LINE3D { COORD3D p1, p2; }; COORD3D transformToCameraCoordinates(const COORD3D & ver_pos, const CAM_TRIG_VALUES & cam_data) { COORD3D result; result.x = cam_data.cos.cam_rot.y * (cam_data.sin.cam_rot.z * (ver_pos.y - cam_data.sin.cam_pos.y) + cam_data.cos.cam_rot.z * (ver_pos.x - cam_data.sin.cam_pos.x)) - cam_data.sin.cam_rot.y * (ver_pos.z - cam_data.sin.cam_pos.z); result.y = cam_data.sin.cam_rot.x * (cam_data.cos.cam_rot.y * (ver_pos.z - cam_data.sin.cam_pos.z) + cam_data.sin.cam_rot.y * (cam_data.sin.cam_rot.z * (ver_pos.y - cam_data.sin.cam_pos.y) + cam_data.cos.cam_rot.z * (ver_pos.x - cam_data.sin.cam_pos.x))) + cam_data.cos.cam_rot.x * (cam_data.cos.cam_rot.z * (ver_pos.y - cam_data.sin.cam_pos.y) - cam_data.sin.cam_rot.z * (ver_pos.x - cam_data.sin.cam_pos.x)); result.z = cam_data.cos.cam_rot.x * (cam_data.cos.cam_rot.y * (ver_pos.z - cam_data.sin.cam_pos.z) + cam_data.sin.cam_rot.y * (cam_data.sin.cam_rot.z * (ver_pos.y - cam_data.sin.cam_pos.y) + cam_data.cos.cam_rot.z * (ver_pos.x - cam_data.sin.cam_pos.x))) - cam_data.sin.cam_rot.x * (cam_data.cos.cam_rot.z * (ver_pos.y - cam_data.sin.cam_pos.y) - cam_data.sin.cam_rot.z * (ver_pos.x - cam_data.sin.cam_pos.x)); return result; } SDL_Rect calculateScreenCoordinates(const COORD3D &c, unsigned res_x, unsigned res_y, double x_tan, double y_tan) { SDL_Rect res; res.x = (short)(((c.x/c.z)/x_tan) * (double)res_x/2.0); res.y = (short)(((c.y/c.z)/y_tan) * (double)res_y/2.0); res.h = 1; res.w = 1; res.x += res_x / 2; res.y += res_y / 2; res.y = res_y - res.y; return res; } COORD3D findIntersectionXY(const LINE3D & line, double z = 0.0) { COORD3D result = {0.0, 0.0, 0.0}; result.z = z; //long version /* double dx = line.p2.x - line.p1.x; double dy = line.p2.y - line.p1.y; double dz = line.p2.z - line.p1.z; double kxz = dx / dz; double kyz = dy / dz; double tz = z - line.p1.z; result.x = line.p1.x + kxz * (tz); result.y = line.p1.y + kyz * (tz); */ //short version result.x = line.p1.x + (((line.p2.x - line.p1.x) * (z - line.p1.z)) / (line.p2.z - line.p1.z)); result.y = line.p1.y + (((line.p2.y - line.p1.y) * (z - line.p1.z)) / (line.p2.z - line.p1.z)); return result; }
Vika oli tuossa
if(r1.z < 0.0) { r1 = findIntersectionXY(*line_it); } if(r2.z < 0.0) { r2 = findIntersectionXY(*line_it); }
Tuota listassa olevaa viiva ei ole käännytty kameran kordinaatistoon niin leikkauspistekin tietysti tuli väärin.
Aihe on jo aika vanha, joten et voi enää vastata siihen.