3

I have a need to add a bunch of dots within the confines of an ellipse. I'm trying to modify the code from the accepted solution to this question, which is set up to use a circle (same width and height) rather than an ellipse. It is also implementing via a HTML <canvas> element, and I need to get it working using p5.js.

Here is my code for the <canvas> element. It seems to be working great. i can size and position the ellipse any which way and the dots are all displayed within it no matter what.

function ellipse(context, cx, cy, rx, ry){
        context.save(); // save state
        context.beginPath();

        context.translate(cx-rx, cy-ry);
        context.scale(rx, ry);
        context.arc(1, 1, 1, 0, 2 * Math.PI, false);

        context.restore(); // restore to original state
        context.stroke();
}


var canvas = document.getElementById("thecanvas");

var ctx = canvas.getContext('2d'),
    count = 1000, // number of random  points
    cx = 300,
    cy = 200,
    w = 50,
    h = 49,
    radius = w;

ctx.fillStyle = '#CCCCCC';
ctx.fillRect(0, 0, canvas.width, canvas.height);

ellipse(ctx, cx, cy, w, h);

// create random points
ctx.fillStyle = '#ffffff';

function dots() {
  while (count) {
      var pt_angle = Math.random() * 2 * Math.PI;
      var pt_radius_sq = Math.random() * radius * radius;
      var pt_x = Math.sqrt(pt_radius_sq) * Math.cos(pt_angle);
      var pt_y = Math.sqrt(pt_radius_sq) * Math.sin(pt_angle);
      ctx.fillRect( ((Math.sqrt(pt_radius_sq) * Math.cos(pt_angle) ) + cx), (((Math.sqrt(pt_radius_sq) * Math.sin(pt_angle))/(w/h)) + cy), 2, 2);
      count--;
  }
}

dots();
<canvas id="thecanvas" width="800" height="800"></canvas>

For some reason, what I believe to be a pretty straight forward to port to p5.js is not working. The dots seem to be contained within the same shaped ellipse as what is defined, but the scale seems to be off and I can't really tell what is causing it. You can see this in action at https://editor.p5js.org/dpassudetti/sketches/YRbLuwoM2 - p5.js code pasted below as well:

var count = 1000, // number of random  points
  cx = 300,
  cy = 200,
  w = 50,
  h = 49,
  radius = w;

function setup() {
  createCanvas(800, 800);

  function dots() {
    fill('green');
    stroke('green');
    while (count) {
      var pt_angle = Math.random() * 2 * Math.PI;
      var pt_radius_sq = Math.random() * radius * radius;
      var pt_x = Math.sqrt(pt_radius_sq) * Math.cos(pt_angle);
      var pt_y = Math.sqrt(pt_radius_sq) * Math.sin(pt_angle);
      square(
        Math.sqrt(pt_radius_sq) * Math.cos(pt_angle) + cx,
        (Math.sqrt(pt_radius_sq) * Math.sin(pt_angle)) / (w / h) + cy,
        2,
        2
      );
      count--;
    }
  }

  fill("#CCCCCC");

  ellipse(cx, cy, w, h);
  dots();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>

If anyone can see what's throwing the scale off for the p5.js version and wouldn't mind pointing me in the right direction, I'd be most appreciative.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
Daveh0
  • 952
  • 9
  • 33

1 Answers1

0

The function you are using to draw the ellipse takes different parameters in the 1st and 2nd case. In one case it's taking the radiuses, and in the other the diameters, so you're off by a factor of 0.5.

I've simplified your code to consider just circles and kept just the w variable, but you can use the code below and add back the h variable if you wish to.

var count = 300, // number of random  points
  cx = 300,
  cy = 200,
  w = 50,
  radius = w / 2;

function setup() {
  createCanvas(800, 800);

  function dots() {
    fill('green');
    stroke('green');
    while (count) {
      const pt_angle = Math.random() * 2 * Math.PI;      
      const px = Math.random() * radius * cos(pt_angle);
      const py = Math.random() * radius * sin(pt_angle);
      
      square(
        px + cx,
        py + cy,
        2,
        2
      );
      count--;
    }
  }

  fill("#CCCCCC");

  ellipse(cx, cy, w, w);
  dots();
}
tada-3429
  • 26
  • 3
  • I had working code for a circle... the ellipse is what I was modifying for. My problem was that I was using `w` for `radius` when i should have been using `w / 2`. Your code showed me that, so if you want to add the `h` back in (so that it answers the question), I'll accept it as the solution. – Daveh0 Feb 15 '23 at 16:49