Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What have you got against the Super Ellipse ? #129

Closed
Carelvd opened this issue Aug 23, 2018 · 1 comment
Closed

What have you got against the Super Ellipse ? #129

Carelvd opened this issue Aug 23, 2018 · 1 comment

Comments

@Carelvd
Copy link

Carelvd commented Aug 23, 2018

Hi,

I was looking at the shapes library and noticed you were missing super ellipses, after a cry I figured I might supply you with some script to generate them but my JavaScript is rubbish so this submission might make you cry a little too. The attached superEllipse.txt should be renamed to superEllipse.js and slapped into the d3/shapes library alongside the circles.js and squares.js (Perhaps consider renaming the file to squircles ? IDK).

I have made the script render 21 points for the shape but you may require higher/lower fidelity.
The following Python script will allow you to generate further scripts with higher/lower fidelity.
To use the script substitute P in the first line with the required number of points.

    t = (P)*4+1
    print("export var superEllipse = {")
    print(" draw : function (context, size) {}")
    print("  var W = size;")
    print("  var H = size;")
    print("  var w = W/2;")
    print("  var h = H/2;")
    print("  var n = 2/4;")
    for i in range(t) :
        if i:
         print(f"  context.lineTo(W/2*Math.sign(Math.cos({i:2}/{t}*2*Math.PI))*Math.pow(Math.abs(Math.cos({i:2}/{t}*2*Math.PI)), n), H/2*Math.sign(Math.sin({i:2}/{t}*2*Math.PI))*Math.pow(Math.abs(Math.sin({i:2}/{t}*2*Math.PI)), n));")
        else :
         print(f"  context.moveTo(W/2*Math.sign(Math.cos({i:2}/{t}*2*Math.PI))*Math.pow(Math.abs(Math.cos({i:2}/{t}*2*Math.PI)), n), H/2*Math.sign(Math.sin({i:2}/{t}*2*Math.PI))*Math.pow(Math.abs(Math.sin({i:2}/{t}*2*Math.PI)), n));")
    print("  contest.closePath();")
    print("  }")
    print("};"

It turns out that most of the detail is in the corners and that the top/bottom/left/right edges are more for making the shape look plumper then a rectangle. The P^{th} point may be thought of as an edge point, while the remaining P-1 points are used to provide detail in the corners, Using a P of 4 seems to give a nice enough shape, that is one for each edge and three points in the corners as below.

image

Otherwise you may know of some bezier curve trickery that might generate the visual result.

Sorry this ain't a formal PR but it was quicker to merely attach a script.

Updated : I had included a half width/height offset which in retrospect was incorrect.

superellipse.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants