• Advertisement

DX11 Directx 11 with C++: how can i draw a circule?

Recommended Posts

i'm trying draw a circule using math:

class coordenates
{
public:
	coordenates(float x=0, float y=0)
	{
		X = x;
		Y = y;
	}
	float X;
	float Y;
};

coordenates RotationPoints(coordenates ActualPosition, double angle)
{
	coordenates NewPosition;
	NewPosition.X = ActualPosition.X*sin(angle) - ActualPosition.Y*sin(angle);
	NewPosition.Y = ActualPosition.Y*cos(angle) + ActualPosition.X*cos(angle);
	return NewPosition;
}

but now i know that these have 1 problem, because i don't use the orign.
even so i'm getting problems on how i can rotate the point.
these coordinates works between -1 and 1 floating points.
can anyone advice more for i create the circule?

Edited by swiftcoder
remove resolved tag

Share this post


Link to post
Share on other sites
Advertisement

	void DrawCircle (coordenates origin, double radius, int tesselation = 24)
	{
	for (int i=0; i<tesselation; i++)
	{
	double angle = double(i) / double(tesselation) * M_PI*2;
	coordenates offset (sin(angle) * radius, cos(angle) * radius);
	DrawPoint (origin.X+offset.X, origin.Y+offset.Y);
	}
	}
	

 

As you say you need a origin but also a radius for the size.

Share this post


Link to post
Share on other sites

i'm sorry, but i need more help.

the zero is the center of window. i have 2 starting dots:
1 - on  center (0,0);
2 - on (7,0).
now the rest is using the angle=angle-1.
and more: i must use radians instead degrees

Share this post


Link to post
Share on other sites

So you want a circle with it's origin at (0,0), and it should intersect the point (7,0)?

DrawCircle (coordenates (0,0), 7);

Would do this if i get you right.

1 hour ago, cambalinho said:

now the rest is using the angle=angle-1.

Don't know what you mean by that.

The angle i calculate is in radians, and it draws the circle with 24 points. (tesselation 360 would draw one point at each degree)

 

1 hour ago, cambalinho said:

the zero is the center of window. i have 2 starting dots:
1 - on  center (0,0);
2 - on (7,0).

Maybe you want to touch both those points with the circle.

So the origin would become:  ( (0,0) + (7,0) ) / 2 = (3.5, 0)

And the radius becomes: ( (0,0) - (7,0) ).Length() / 2 = 3.5

 

(you could draw a picture if that still does not help)

Edited by JoeJ

Share this post


Link to post
Share on other sites

for now i only get 2 dots :(
the center and 1 on right :(

i'm sorry but let me ask in a different way(math way):
1 - we have the point A(20,30);
2 - we must rotate the point A by 30º degrees;
3 - how we calculate the point B?

Share this post


Link to post
Share on other sites
37 minutes ago, cambalinho said:

for now i only get 2 dots :(
the center and 1 on right :(

i'm sorry but let me ask in a different way(math way):
1 - we have the point A(20,30);
2 - we must rotate the point A by 30º degrees;
3 - how we calculate the point B?

For this your code should work:

coordenates rotated =  RotationPoints(coordenates (20,30), 30/180*M_PI);

The center of rotation would by (0,0) of course.

 

Oh wait, there is a bug:

NewPosition.X = ActualPosition.X*sin(angle) - ActualPosition.Y*sin(angle); // x affected by sin twice

NewPosition.Y = ActualPosition.Y*cos(angle) + ActualPosition.X*cos(angle); // y affected by cos twice

 

try this instead, should be correct:

NewPosition.X = ActualPosition.X*cos(angle) - ActualPosition.Y*sin(angle);

NewPosition.Y = ActualPosition.X*sin(angle) + ActualPosition.Y*cos(angle);

Share this post


Link to post
Share on other sites
vector<Vertex> CirclePoints(float radius)
{
	vector<Vertex> AllPoints;
	AllPoints.resize(362+361*3);
	AllPoints[0]= Vertex(0, 0, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
	AllPoints[1] = Vertex(radius, 0, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
	for (float i = 2.0f; i < AllPoints.size(); i=i+0.125f)
	{

		AllPoints[(int)i] = Vertex(radius *cos(i), radius *sin(i), 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
	}	
	return AllPoints;
}

finally i get results:
5a82f1d14194b_SemTtulo.png.a18315375fafcd292946e0d7d99df859.png

now you see why these line:

vector<Vertex> AllPoints;
	AllPoints.resize(362+361*3);

but i need more advice, please: how can i make more precision?

Share this post


Link to post
Share on other sites

That's a lot of bad practice:

 

for (float i = 2.0f; i < AllPoints.size(); i=i+0.125f)

// this may be dangerous, due to floating point precision you may run the loop once more than intended!

// Also, why starting from 2.0f?

{

AllPoints[(int)i] = // you round i to the nearest integer, so you constantly overwrite previous results 8 times and waste them

Vertex(radius *cos(i), radius *sin(i), 0.0f, 1.0f, 0.0f, 0.0f, 0.0f); // i is not a nice angle in radians, instead of going from 0 to 2PI, it goes from 2 to 362+361*3 - you get a circle just by running around the circle often enough to hit all positions by luck

}

 

I'll modify my first snippet so it fits your needs:

vector<Vertex> DrawCircle (float radius, int tesselation = 48)
{
	vector<Vertex> AllPoints; 
	AllPoints.resize(tesselation);

	for (int i=0; i<tesselation; i++) // running the loop with integer guarantees we run it exactly (tesselation) times
	{
		float angle = 
			float(i) / float(tesselation) // this goes from 0 to almost 1
			* M_PI*2; // 2PI is 360 degrees, so multiply by that to get angles between 0 and almost 2PI

		AllPoints[(int)i] = Vertex(radius * cos(angle), radius * sin(angle), 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
	}

	return AllPoints;
}

This code should work i hope.

You may want to set high tesselation so there are no holes between just 48 points.

Or better, draw lines between 2 points in order.

Share this post


Link to post
Share on other sites

 #define M_PI       3.14159265358979323846   // pi

from math.h

tesselation is how many points you use for the circle

Share this post


Link to post
Share on other sites

- tesselation is how many points we use for draw the circle and that it's the draw quality, right?

- i'm sorry, but can you explain better how these math works?

float angle = 
			float(i) / float(tesselation) // this goes from 0 to almost 1
			* M_PI*2;

i'm confused on how you get the angle

Share this post


Link to post
Share on other sites
6 minutes ago, cambalinho said:

- tesselation is how many points we use for draw the circle and that it's the draw quality, right?

yes.

 

To explain the angle, let's use degrees instead with this example:

int tesselation = 4;

for (int i=0; i<tesselation; i++)

{

float t= float(i) / float(tesselation);

float angleDegrees = t * 360;

}

 

If we plot i, t and angleDegrees, we get:

0  0  0

1  0.25  90

2  0.5  180

3  0.75  270

So it's a simple linear mapping from tho loop counter to the angle of one full revolution which has 360 degrees.

We do not need a final value of 360 degrees, because that would give the same result as the starting angle of 0. That's what i mean with 'almost'.

With radians it's the same math, but 360 degrees is 2*PI radians.

 

 

 

Share this post


Link to post
Share on other sites
12 minutes ago, cambalinho said:

correct me 1 thing: if i use 270 instead 360, we make a open circule or even a curve, right?

Yes, we would call this an 'arc', usually defined by starting and ending angle.

 

Edit: additionally, if you affect the radius by t, e.g. radius = 1+t*2, you can draw a spiral (using multiple revolutions eventually like 360 * 3)

Edited by JoeJ

Share this post


Link to post
Share on other sites
vector<Vertex> DrawSpiralArc (float radius0, float radius1, float angle0, float angle1, int tesselation = 48)
{
	vector<Vertex> AllPoints; 
	AllPoints.resize(tesselation);

	for (int i=0; i<tesselation; i++) // running the loop with integer guarantees we run it exactly (tesselation) times
	{
		float t = 
			float(i) / float(tesselation); // this goes from 0 to almost 1
		float angle = 
			angle0 * (1.0f-t) + angle1 * t;
		float radius = 
			radius0 * (1.0f-t) + radius1 * t;

		AllPoints[(int)i] = Vertex(radius * cos(angle), radius * sin(angle), 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
	}

	return AllPoints;
}

... combining all ideas

To draw a 90 degrees arc: DrawSpiralArc (20, 20, 45/180*M_PI, 135/180*M_PI, 200);

To draw spiral: DrawSpiralArc (0, 20, 0, M_PI*8, 200);

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By osiris_dev
      Hello!
      Have a problem with reflection shader for D3D11:
      1>engine_render_d3d11_system.obj : error LNK2001: unresolved external symbol IID_ID3D11ShaderReflection
      I tried to add this:
      #include <D3D11Shader.h>
      #include <D3Dcompiler.h>
      #include <D3DCompiler.inl>
      #pragma comment(lib, "D3DCompiler.lib")
      //#pragma comment(lib, "D3DCompiler_47.lib")
      As MSDN tells me but still no fortune. I think lot of people did that already, what I missing?
       
    • By trojanfoe
      Hi there, this is my first post in what looks to be a very interesting forum.
      I am using DirectXTK to put together my 2D game engine but would like to use the GPU depth buffer in order to avoid sorting back-to-front on the CPU and I think I also want to use GPU instancing, so can I do that with SpriteBatch or am I looking at implementing my own sprite rendering?
      Thanks in advance!
    • By Matt_Aufderheide
      I am trying to draw a screen-aligned quad with arbitrary sizes.
       
      currently I just send 4 vertices to the vertex shader like so:
      pDevCon->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
      pDevCon->Draw(4, 0);
       
      then in the vertex shader I am doing this:
      float4 main(uint vI : SV_VERTEXID) : SV_POSITION
      {
       float2 texcoord = float2(vI & 1, vI >> 1);
      return float4((texcoord.x - 0.5f) * 2, -(texcoord.y - 0.5f) * 2, 0, 1);
      }
      that gets me a screen-sized quad...ok .. what's the correct way to get arbitrary sizes?...I have messed around with various numbers, but I think I don't quite get something in these relationships.
      one thing I tried is: 
       
      float4 quad = float4((texcoord.x - (xpos/screensizex)) * (width/screensizex), -(texcoord.y - (ypos/screensizey)) * (height/screensizey), 0, 1);
       
      .. where xpos and ypos is number of pixels from upper right corner..width and height is the desired size of the quad in pixels
      this gets me somewhat close, but not right.. a bit too small..so I'm missing something ..any ideas?
       
      .
    • By Stewie.G
      Hi,
      I've been trying to implement a gaussian blur recently, it would seem the best way to achieve this is by running a bur on one axis, then another blur on the other axis.
      I think I have successfully implemented the blur part per axis, but now I have to blend both calls with a proper BlendState, at least I think this is where my problem is.
      Here are my passes:
      RasterizerState DisableCulling { CullMode = BACK; }; BlendState AdditiveBlend { BlendEnable[0] = TRUE; BlendEnable[1] = TRUE; SrcBlend[0] = SRC_COLOR; BlendOp[0] = ADD; BlendOp[1] = ADD; SrcBlend[1] = SRC_COLOR; }; technique11 BlockTech { pass P0 { SetVertexShader(CompileShader(vs_5_0, VS())); SetGeometryShader(NULL); SetPixelShader(CompileShader(ps_5_0, PS_BlurV())); SetRasterizerState(DisableCulling); SetBlendState(AdditiveBlend, float4(0.0, 0.0, 0.0, 0.0), 0xffffffff); } pass P1 { SetVertexShader(CompileShader(vs_5_0, VS())); SetGeometryShader(NULL); SetPixelShader(CompileShader(ps_5_0, PS_BlurH())); SetRasterizerState(DisableCulling); } }  
      D3DX11_TECHNIQUE_DESC techDesc; mBlockEffect->mTech->GetDesc( &techDesc ); for(UINT p = 0; p < techDesc.Passes; ++p) { deviceContext->IASetVertexBuffers(0, 2, bufferPointers, stride, offset); deviceContext->IASetIndexBuffer(mIB, DXGI_FORMAT_R32_UINT, 0); mBlockEffect->mTech->GetPassByIndex(p)->Apply(0, deviceContext); deviceContext->DrawIndexedInstanced(36, mNumberOfActiveCubes, 0, 0, 0); } No blur

       
      PS_BlurV

      PS_BlurH

      P0 + P1

      As you can see, it does not work at all.
      I think the issue is in my BlendState, but I am not sure.
      I've seen many articles going with the render to texture approach, but I've also seen articles where both shaders were called in succession, and it worked just fine, I'd like to go with that second approach. Unfortunately, the code was in OpenGL where the syntax for running multiple passes is quite different (http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/). So I need some help doing the same in HLSL :-)
       
      Thanks!
    • By Fleshbits
      Back around 2006 I spent a good year or two reading books, articles on this site, and gobbling up everything game dev related I could. I started an engine in DX10 and got through basics. I eventually gave up, because I couldn't do the harder things.
      Now, my C++ is 12 years stronger, my mind is trained better, and I am thinking of giving it another go.
      Alot has changed. There is no more SDK, there is evidently a DX Toolkit, XNA died, all the sweet sites I used to go to are 404, and google searches all point to Unity and Unreal.
      I plainly don't like Unity or Unreal, but might learn them for reference.
      So, what is the current path? Does everyone pretty much use the DX Toolkit? Should I start there? I also read that DX12 is just expert level DX11, so I guess I am going DX 11.
      Is there a current and up to date list of learning resources anywhere?  I am about tired of 404s..
       
       
  • Advertisement