processing / p5.js

p5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. http://twitter.com/p5xjs —
http://p5js.org/
GNU Lesser General Public License v2.1
21.69k stars 3.33k forks source link

Refactor 2d_primitives.js #6686

Open JustZambetti opened 10 months ago

JustZambetti commented 10 months ago

Increasing Access

It would make the code shorter and more readable

Most appropriate sub-area of p5.js?

Feature enhancement details

I think that 2d_primitives.js could be refactored a bit. These are some suggestions:

_normalizeArcAngles signature

Problems:

From this:

p5.prototype._normalizeArcAngles = (
  start,
  stop,
  width,
  height,
  correctForScaling
)

To this:

p5.prototype._normalizeArcAngles = (
  size, //(width, height),
  drawRegion, //(startAngle, stopAngle)
  angleBehaviourOnScale //(angleBehaviourOnScale.Stretch, angleBehaviourOnScale.KeepRelative)
)

_normalizeArcAngles angle constraint

Code:

  // Constrain both start and stop to [0,TWO_PI).
  start = start - constants.TWO_PI * Math.floor(start / constants.TWO_PI);
  stop = stop - constants.TWO_PI * Math.floor(stop / constants.TWO_PI);

Problems:

Code:

separation = Math.min(
    Math.abs(start - stop),
    constants.TWO_PI - Math.abs(start - stop)
  );

Problem:

_normalizeArcAngles angle scaling

Code:

// Optionally adjust the angles to counter linear scaling.
  if (correctForScaling) {
    if (start <= constants.HALF_PI) {
      start = Math.atan(width / height * Math.tan(start));
    } else if (start > constants.HALF_PI && start <= 3 * constants.HALF_PI) {
      start = Math.atan(width / height * Math.tan(start)) + constants.PI;
    } else {
      start = Math.atan(width / height * Math.tan(start)) + constants.TWO_PI;
    }
    if (stop <= constants.HALF_PI) {
      stop = Math.atan(width / height * Math.tan(stop));
    } else if (stop > constants.HALF_PI && stop <= 3 * constants.HALF_PI) {
      stop = Math.atan(width / height * Math.tan(stop)) + constants.PI;
    } else {
      stop = Math.atan(width / height * Math.tan(stop)) + constants.TWO_PI;
    }
  }

Problems:

makeDrawRegionRelative(region){ region.start = makeAngleRelative(region.start); region.stop = makeAngleRelative(region.stop); return region; }

//I don't understand the math behind completely so I'm not able to simplify it further, // this method is actually too long but it's still an improvement //TODO: simplify this method makeAngleRelative(angle){ const THREE_PI = 3 * constants.HALF_PI; let offsetAngle = 0;

if(angle < constants.PI) offsetAngle = 0; else if (angle <= THREE_PI) offsetAngle = constants.PI; else offsetAngle = constants.TWO_PI;

return Math.atan(width / height * Math.tan(angle)) + offsetAngle; }


# _normalizeArcAngles angle last check
## Code:
```js
// Ensure that start <= stop < start + TWO_PI.
if (start > stop) {
  stop += constants.TWO_PI;
}

Problem:

But I would leave the comment inside of the function because it's not obvious

arc function signature

Problem:

Code:

// if the current stroke and fill settings wouldn't result in something
// visible, exit immediately
if (!this._renderer._doStroke && !this._renderer._doFill) {
  return this;
}
if (start === stop) {
  return this;
}

Problem:

Code:

// p5 supports negative width and heights for ellipses
w = Math.abs(w);
h = Math.abs(h);

Problem:

Code:

  p5.prototype.circle = function() {
    p5._validateParameters('circle', arguments);
    const args = Array.prototype.slice.call(arguments, 0, 2);
    args.push(arguments[2]);
    args.push(arguments[2]);
    return this._renderEllipse(...args);
  }

Problem:

Code:

p5.prototype._renderEllipse = function(x, y, w, h, detailX){
}

Problem:

Code:

// p5 supports negative width and heights for rects
  if (w < 0) {
    w = Math.abs(w);
  }

  if (typeof h === 'undefined') {
    // Duplicate 3rd argument if only 3 given.
    h = w;
  } else if (h < 0) {
    h = Math.abs(h);
  }

Opinion:

I noticed that in many functions x and y, width and height are separate arguments but I think it's preferable to use position and size instead.

I would like to be assigned to this issue.

davepagurek commented 10 months ago

Hi, thanks for your interest in this! Some general comments:

TanmayDhobale commented 10 months ago

Hi @davepagurek, I noticed some issues in the 2D Primitives test suite and made the following improvements:

  1. In the p5.prototype.ellipse suite, addressed the missing param #2 and #3 issues.
  2. In the p5.prototype.rect suite, fixed the case where missing param #5 was not throwing a validation error.
  3. Updated the p5.prototype.square suite to handle missing param #3 appropriately.
  4. Fixed a bug in the p5.prototype.line suite where incorrect parameters were not triggering validation errors.
  5. Improved error messaging in the p5.prototype.triangle suite for better clarity.

Before proceeding, I wanted to check if you have any specific considerations or if it's okay for me to submit a pull request with these changes. Looking forward to your feedback.

Best regards, tanmay

limzykenneth commented 10 months ago

There may be a case for this to be looked at as part of the 2.0 RFC at #6678. If so we can turn this into a proposal for refactoring the 2D renderer in general.