Jump to content
  • Advertisement
Sign in to follow this  
CelticSir

Draw only portions of the circle visible to the user

This topic is 1085 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a basic output of a circle, of which I want to optimize by only drawing angle ranges that are visible. For me this should hopefully improve performance, as I currently am getting serious performance loss drawing very large circles and need to reduce the amount of output to keep it efficient.

 

My current draw code: 

function draw(){
  ctx.clearRect(0,0,canvas.width,canvas.height);

  ctx.save();  
    ctx.translate(camera.x,camera.y);
    ctx.beginPath();
    ctx.arc(pos.x,pos.y,radius,0,2*Math.PI);
    ctx.stroke();
  ctx.restore();
  
  requestAnimationFrame(draw);
}

draw();

I only need to calculate the perimeter of the circle not the inner body of it, so if the edge of the circle is off screen it would not draw a circle.

 

This is a visual example of what I refer to:

Ko7Xz.jpg

 

There are certain situations that have to be taking into account for calculating the angles. The size of the radius, the origin position of the circle and position of the camera. I initially tried comparing radius size versus (canvas width/2) but soon realized that was incorrect math logic. And so, i have no idea how i would approach the issue.

 

What is the best way to achieve this in JavaScript?

 

EDIT: added basic javascript code example: https://jsfiddle.net/44tawd81/ you can click and drag the circle.

Edited by thefollower

Share this post


Link to post
Share on other sites
Advertisement

Well i tried two semi circles, which was actually required in order for me to draw objects with the right depth perception and ordering for sprites. But could not work out the maths.

Share this post


Link to post
Share on other sites

I was thinking much simpler, like

ctx.beginPath();
ctx.arc(pos.x,pos.y,radius, 0, Math.PI / 2);
ctx.stroke();

ctx.beginPath();
ctx.arc(pos.x,pos.y,radius, Math.PI / 2, Math.PI);
ctx.stroke();

ctx.beginPath();
ctx.arc(pos.x,pos.y,radius, Math.PI, 3 * Math.PI / 2);
ctx.stroke();

ctx.beginPath();
ctx.arc(pos.x,pos.y,radius, 3 * Math.PI / 2, 2 * Math.PI);
ctx.stroke();

I don't know enough Javascript to know whether the above is actually allowed, but I hope you get the idea.

 

The engine can perhaps not skip drawing a circle that is partially visible, only (parts of a) circle that is completely invisible.

By splitting it in 4 parts, you are giving the engine an option to skip drawing some parts.

 

This is all quite highly speculative though, but it seems simple enough to just try and see.

Share this post


Link to post
Share on other sites

@Crossbones, i am not 100% sure on how the JavaScript engine works. If i have a clip which is smaller than my circle, does the browser still process the entire circle or just whats relevant to the clip ? There is woeful documentation on techy stuff like that.

Also, i would still have to call the function to draw the circle which surely it would be more efficient if i skipped the call entirely, if for example the circle was bigger than the entire output and so you never saw the perimeter?

Edited by thefollower

Share this post


Link to post
Share on other sites

Be sure to profile where the time is being spent. Too often, people are "sure" that the problem is in a section of code and it turns out they're wrong.

 

Also, even if you can't figure out the math, you can try to draw partial circles just to see if it speeds things up. The arc function might turn out to be even slower than the circle function and if so, you'll need to think of a different way to solve it. One possibility is you could have a circle sprite, and draw it scaled appropriately. Again, this may or may not be faster. Time it! :)

 

Maybe you can limit the size of the circles. Why do you need such overly large circles? Maybe we can help come up with a better solution to your problem?

 

- Eck

Share this post


Link to post
Share on other sites

Be sure to profile where the time is being spent. Too often, people are "sure" that the problem is in a section of code and it turns out they're wrong.

 

Also, even if you can't figure out the math, you can try to draw partial circles just to see if it speeds things up. The arc function might turn out to be even slower than the circle function and if so, you'll need to think of a different way to solve it. One possibility is you could have a circle sprite, and draw it scaled appropriately. Again, this may or may not be faster. Time it! smile.png

 

Maybe you can limit the size of the circles. Why do you need such overly large circles? Maybe we can help come up with a better solution to your problem?

 

- Eck

 I don't think there is a circle function i believe arc is the one. 

I did do a cpu profile, and 80% of process goes to the "stroke" function which deals with giving the circle its perimeter line. The circles are large because it's a solar system i am trying to make, although not fully to scale, it is rather large none the less ;)

Edited by thefollower

Share this post


Link to post
Share on other sites

Did you try just not drawing circles bigger than some X? While the image is obviously broken then, it should give you a big boost in performance if you are correct.

That is, you can do simple experiments to check your own conclusions, before going in and properly fix it.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!