Norhther
Norhther

Reputation: 500

Consistent way to draw ellipsis area

I'm trying to make a simple game in Processing. The canvas consist of two ellipsis, as in the following image:

enter image description here

This is my code:

var angle = Math.random()*360;
var diff = 1;
var region = {};
var first = true;
var o;
centerX = 250; centerY = 250; radiusX = 150; radiusY = 200;
var score = 0;

function setup() {
    createCanvas(500, 500);
}

function draw() {

    o = ellipseGetPoint(250,250,150,200,angle);
    angle += diff;
    background(220);
    stroke("black");
    fill("#333333");
    ellipse(250,250,300,400);
    stroke("white")
    drawRegion(250,250,150,200);

    stroke("red");
    line(250,250,o.pointX, o.pointY);
    fill("#999999");
    stroke(0);
    ellipse(250,250,200,300);

    textSize(50);
    text(str(score), 20, 490);
    fill(0, 102, 153);
}

function ellipseGetPoint(centerX, centerY, radiusX, radiusY, angle) {
    let o = {};
    let pointX = centerX + radiusX * Math.cos(angle*Math.PI / 180);
    let pointY = centerY + radiusY * Math.sin(angle*Math.PI / 180);
    o.pointX = Math.floor(pointX);
    o.pointY = Math.floor(pointY);
    o.angle = angle;
    return o;
}

function drawRegion(centerX, centerY, radiusX, radiusY) {
  if (first) {
    first = false;
    region = ellipseGetPoint(centerX, centerY, radiusX, radiusY, Math.random()*360);
  }
  let currentX = region.pointX;
  let currentY = region.pointY;
  let t = 1;
  for (let i = 0; i < 1000; i++) {
      line(250,250, currentX, currentY);
      currentX = centerX + radiusX * Math.cos(t*region.angle*Math.PI / 180)
      currentY = centerY + radiusY * Math.sin(t*region.angle*Math.PI / 180)
      t+=0.00015;
  } 
}

function keyPressed() {
  if (key  == " ") {
    diff*=-1;
  }

  let x = Math.floor(o.pointX);
  let y = Math.floor(o.pointY);
  let t = 1;
  for (let i = 0; i < 1000; i++) {
      currentX = centerX + radiusX * Math.cos(t*region.angle*Math.PI / 180)
      currentY = centerY + radiusY * Math.sin(t*region.angle*Math.PI / 180)
      t+=0.00015;
    if (Math.floor(currentX) == x) {
      first = true
      }
  }
  if (first) ++score;
  else --score;
  if (diff > 0 && diff < 3) diff += 0.1;
  else if (diff > -3) diff -= 0.1;
}

The problem I'm facing is that, making the white area, I'm getting a different size of area depending of where it spawns. I did it by getting a random point and adding a little offset, and drawing that 1000 times. I know this is not a good way to do it, but I don't know how to generate that region. Any way to do it?

Upvotes: 1

Views: 50

Answers (2)

Rabbid76
Rabbid76

Reputation: 210909

Use arc() to draw an elliptical arc segment.
Compute the start and end angle in ellipseGetPoint and draw the arc:

function drawRegion(centerX, centerY, radiusX, radiusY) {
    if (first) {
        first = false;
        region = ellipseGetPoint(centerX, centerY, radiusX, radiusY, Math.random()*360);
    }

    let t = 1;
    let start = t*region.angle*Math.PI / 180;
    t+= 0.15;
    let end = t*region.angle*Math.PI / 180;

    arc(centerX, centerY, radiusX*2, radiusY*2, start, end)
}

Note, you have to set the fill color before drawing the arc:

stroke("white")
drawRegion(250,250,150,200);

See the example:

var angle = Math.random()*360;
var diff = 1;
var region = {};
var first = true;
var o;
centerX = 250; centerY = 250; radiusX = 150; radiusY = 200;
var score = 0;

function setup() {
    createCanvas(500, 500);
}

function draw() {

    o = ellipseGetPoint(250,250,150,200,angle);
    angle += diff;
    background(220);
    stroke("black");
    fill("#333333");
    ellipse(250,250,300,400);
    fill("white")
    stroke("white")
    drawRegion(250,250,150,200);

    stroke("red");
    line(250,250,o.pointX, o.pointY);
    fill("#999999");
    stroke(0);
    ellipse(250,250,200,300);

    textSize(50);
    text(str(score), 20, 490);
    fill(0, 102, 153);
}

function ellipseGetPoint(centerX, centerY, radiusX, radiusY, angle) {
    let o = {};
    let pointX = centerX + radiusX * Math.cos(angle*Math.PI / 180);
    let pointY = centerY + radiusY * Math.sin(angle*Math.PI / 180);
    o.pointX = Math.floor(pointX);
    o.pointY = Math.floor(pointY);
    o.angle = angle;
    return o;
}

function drawRegion(centerX, centerY, radiusX, radiusY) {
    if (first) {
        first = false;
        region = ellipseGetPoint(centerX, centerY, radiusX, radiusY, Math.random()*360);
    }

    let t = 1;
    let start = t*region.angle*Math.PI / 180;
    t+= 0.15;
    let end = t*region.angle*Math.PI / 180;
    
    arc(centerX, centerY, radiusX*2, radiusY*2, start, end)
}

function keyPressed() {
  if (key  == " ") {
    diff*=-1;
  }

  let x = Math.floor(o.pointX);
  let y = Math.floor(o.pointY);
  let t = 1;
  for (let i = 0; i < 1000; i++) {
      currentX = centerX + radiusX * Math.cos(t*region.angle*Math.PI / 180)
      currentY = centerY + radiusY * Math.sin(t*region.angle*Math.PI / 180)
      t+=0.00015;
    if (Math.floor(currentX) == x) {
      first = true
      }
  }
  if (first) ++score;
  else --score;
  if (diff > 0 && diff < 3) diff += 0.1;
  else if (diff > -3) diff -= 0.1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>

Upvotes: 0

laancelot
laancelot

Reputation: 3207

Maybe you're looking for arc?

void draw() {
  arc(50, 50, 80, 80, 0, QUARTER_PI, PIE);
}

ARC

Here's the documentation for more details. I think you'll love this.

Upvotes: 1

Related Questions