HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Rotating 3D wireframe

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
wireframerotatingstackoverflow

Problem

This code consumes a lot of CPU. Could you tell me where it is possible to improve the code or change the way rendering?

Or it is possible to reduce the overhead of calculations? If you are using only 1 point when drawing the load on the CPU is not changed! Load 50-60%

Ubuntu 15.04 / intel® Core ™ i5-3230M CPU @ 2.60GHz × 4

Run the code without rendering lines - 20-30% load. So they are quite costly...

Demo: http://codepen.io/jonfint/full/VLYMMW



var canvas = document.getElementById("canvas"),
ctx = canvas.getContext('2d'),
points = [],
r = 0;

var a = 50; // количество точек
var b = 1; // скорость поворота
var d = 20; // увеличение радиуса*
var minDist = 200; // ??
var dist; // ??

canvas.width = 500; // Originally window.innerWidth, changed for Stack Snippet
canvas.height = 600; // Originally window.innerHeight, changed for Stack Snippet

for (var i = 0; i
`

Solution

I profiled your code and calling your render function takes 3.1-4.2 ms on my machine (i7 2.1 ghz running chrome/linux). I managed to cut that to only 0.6 ms by removing what is AFAIK the performance killer in this type of drawings using the canvas API. Check it out for yourself http://codepen.io/anon/pen/QbwQmo

The performance killer that I'm talking about is that you're drawing a million separate paths instead of batching them all in a single .beginPath ... .stroke. The catch is however that you can't have multiple colors (alpha levels) in the same path - so changing the color for every segment is not possible anymore. You could instead bucketize the paths - choose 10 shades of grey and add segments to these buckets; then call .stroke for each bucket (that'll amount to max 10 calls - way better than (50*50 which is what you can have)). The only way to overcome this limitation of the canvas API is to not use it in the first place :). Instead use a WebGL renderer (pixi.js, goo.js, three.js).

There's another thing which you can do to increase performance especially if you'll want more than 50 points. Right now you're checking every point against every other point. The number of calls to distance (not the best name btw) grows quadratically with the number of points. You can reduce the number of checks by discarding points that are too far - and you achieve this by splitting the whole space ([0...600] x [0...600]) into smaller buckets of 100 x 100 or something. You'd have to update the buckets every frame such that they contain the points that lie within their bounds. The upside is that you only need to check points in nearby buckets and not in the whole space.

(Disclaimer: I am a dev of goo.js)

Context

StackExchange Code Review Q#88140, answer score: 3

Revisions (0)

No revisions yet.