Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: 3D viivojen piirtäminen

Lahha [05.11.2010 12:42:38]

#

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;
}

Lahha [07.11.2010 23:33:45]

#

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.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta