Quantcast
Channel: Visual C forum
Viewing all articles
Browse latest Browse all 15302

Converting Cartesian Coordinates to Screen Coordinates.

$
0
0

I'm doing some graphing with Direct2D with the mathematical function sqrt(x) (Square root of x) . I have written some code that translates Cartesian to screen co-ordinates and for the most part it is working however I am experiencing some floating point trouble as my "zoom level" increases. I think the value of 

fPointsRightXpx[iIndexXpxCount][1] = (fOriginY - ( ((float)dPlotPointsRightFX[iIndexXpxCount][1]) * (fClientAreaY / 2) / (fScaleFactor)));

is rolling over. Is there something I can do to prevent this from occurring? My scale factor is half the visible units of x measured from left to right across the screen.


My code is as follows:

			/******************************************/
			/*plot points to the right of the origin***/
			/******************************************/
			//for each increment of x visible to the right of the origin point on the screen
			//calculate a f(X) and store the x and f(x) values in the dPlotPointsRightFX array
			//if there is an infinity value set the infinity flag. The default value for iSegmentsPerHalf
			//is 1000
			int iSegmentsPerHalf = 1000;

			double dDistRightXpx = (fClientAreaX - fOriginX);
			double dOneGrid = fScaleFactor / 10;
			double dOneGridpx = (fClientAreaX / 2) / 10;
			double dDistRightX = (dDistRightXpx / dOneGridpx) * dOneGrid;

			double dDistLeftXpx = (fOriginX);
			double dDistLeftX = (dDistLeftXpx / dOneGridpx) * dOneGrid;

			double dPlotPointsRightFX[10000][2] = { NULL };
			int iPlotPointsFXCount = 0;

			for (x = double(0); x <= double(dDistRightX) + (fScaleFactor / iSegmentsPerHalf); x += fScaleFactor / iSegmentsPerHalf)
			{
				//get the current f(x) for the value at x declared in for
				double dCurrentEquationFX = expression.value();

				//store the current x
				dPlotPointsRightFX[iPlotPointsFXCount][0] = x;
				if (dCurrentEquationFX==INFINITY)
				{
					infinityY = true;
				}
				if (dCurrentEquationFX == -INFINITY)
				{
					infinityY = true;
				}
				//store the calculated f(x) for the current x
				dPlotPointsRightFX[iPlotPointsFXCount][1] = dCurrentEquationFX;

				//increment the counter so on the next iteration of for
				//we move to a new element of the array
				iPlotPointsFXCount++;
			}

			
			//convert the points from cartesian co-ordinates
			//to screen co-ordinates and store in fPointsRightXpx
			int iIndexXpxCount = 0;
			float fLastIndexXpx = fOriginX;
			float fPointsRightXpx[10000][2] = { 0.0f };

			//set fIndexXpx to the origin point of X on the screen which is movable and is stored in
			//fOriginX.
			for (float fIndexXpx = fOriginX; fIndexXpx <= fClientAreaX; fIndexXpx += (fClientAreaX / 2) / iSegmentsPerHalf)
			{
				fPointsRightXpx[iIndexXpxCount][0] = fIndexXpx;

				//Convert the f(x) from cartesian co-ordinates to screen co-ordinates. I'm doing some calculations with the function
				//sqrt(x) and as the zoom level goes positive and f(x) values move further and further above the screen that the
				//value stored in fPointsRightXpx[iIndexXpxCount][1] is rolling over. I'm not sure yet what to do to prevent this
				//from happening but I'm working on it. I know there is a problem because at zoom level 116 there are positive values in
				//fPointsRightXpx[iIndexXpxCount][1] when there are supposed to be negative ones. For zoom levels less than 116 the function
				//is working as intended. I'm curious right now why for zoom level 116 this computation is not returning -1.#INF
				fPointsRightXpx[iIndexXpxCount][1] = (fOriginY - ( ((float)dPlotPointsRightFX[iIndexXpxCount][1]) * (fClientAreaY / 2) / (fScaleFactor)));
				iIndexXpxCount++;
			}

			//plot the points in increments of x to the screen starting at the origin and working to the right
			iIndexXpxCount = 0;
			fLastIndexXpx = fOriginX;
			for (float fIndexXpx = fOriginX; fIndexXpx <= fClientAreaX; fIndexXpx += (fClientAreaX/2)/iSegmentsPerHalf )
			{
				//helper ellipses
				//ellipse = D2D1::Ellipse(D2D1::Point2F(fIndexXpx, fOriginY), 3, 3);
				//m_pRenderTarget->FillEllipse(ellipse, m_pCornflowerBlueBrush);
				//ellipse = D2D1::Ellipse(D2D1::Point2F(fIndexXpx, (dTranslatedY)), 3, 3);
				//m_pRenderTarget->FillEllipse(ellipse, m_pCornflowerBlueBrush);
				m_pRenderTarget->DrawLine(
					D2D1::Point2F(fIndexXpx, fOriginY),
					D2D1::Point2F(fIndexXpx, fPointsRightXpx[iIndexXpxCount][1]),
					m_pCornflowerBlueBrush,
					0.5
					);

				if (iIndexXpxCount > 0)
				{
					m_pRenderTarget->DrawLine(
						D2D1::Point2F(fLastIndexXpx, fPointsRightXpx[iIndexXpxCount-1][1]),
						D2D1::Point2F(fIndexXpx, fPointsRightXpx[iIndexXpxCount][1]),
						m_pRedBrush,
						2.0
						);
				}

				fLastIndexXpx = fIndexXpx;
				iIndexXpxCount ++;
			}
			/******************************************/
			/*end plot point to the right******************/
			/******************************************/

At my "zoomLevel" 116 which is viewing a smaller area of Cartesian space than "zoomLevel" 0 it appears that the value in:

fPointsRightXpx[iIndexXpxCount][1] = (fOriginY - ( ((float)dPlotPointsRightFX[iIndexXpxCount][1]) * (fClientAreaY / 2) / (fScaleFactor)));

is rolling over. Is there something I can do to prevent this from happening? I commented that area of the code describing what is happening.

Also it seems that:

				if (dCurrentEquationFX == -INFINITY)
				{
					infinityY = true;
				}

is causing "C4056: overflow in floating-point constant arithmetic". My intent is to check for a negative infinity. I need my program to do something if there is a negative infinity and something different if there is a positive infinity. Is there something that can be done about ""C4056: overflow in floating-point constant arithmetic" in this case?

Thank You!








Viewing all articles
Browse latest Browse all 15302

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>