How to calculate the golden ratio?
#includepath "~/Documents/;%USERPROFILE%Documents"; // eslint-disable-line
#include "basiljs/bundle/basil.js"; // eslint-disable-line
// A simple sketch makes use of the goldenRatio
//
/**
* A sample function that shows how to calculate the golden ratio
* The logic is extracted from https://jumk.de/goldener-schnitt/
* by Jürgen Kummer
* It tries to catch errors made by the user but the usage should be:
*
* Provide a value for a or b or ab
*
* @param {Number} a value a the bigger of the two
* @param {Number} b value b the smaller of the two
* @param {Number} ab the sum of a + b
* @return {Object} Returns an object like this {a: Number, b: Number, ab: Number};
*/
function goldenRatio(a, b, ab) {
// phi or φ https://de.wikipedia.org/wiki/Phi
var φ = 1.6180339887498948; // this is phi
if (a === null && b === null && ab === null) {
// if no value is given return an error
return Error('No values given.\nPlease provide just one value for a or b or ab');
} else if (
(a !== null && b !== null) || (a !== null && ab !== null) || (b !== null && ab !== null)) {
// if more then one value is given return an error
return Error('To many values.\nPlease provide just one value for a or b or ab');
}
// now we only have one value.
// lets calc the according others
//
if (a !== null) {
// a is given
b = null;
ab = null;
b = a / φ;
ab = a + b;
} else if (b !== null) {
// b is given
a = null;
ab = null;
a = φ * b;
ab = a + b;
} else if (ab !== null) {
// ab is given
a = null;
b = null;
a = ab / φ;
b = a / φ;
}
// give back the result
return {
a: a,
b: b,
ab: ab
};
};
function draw() {
var rectWidth = b.random(123, 234); // this is some random number as basis for the calculation
var ratio = goldenRatio(rectWidth, null, null); // calc the ratio for that
// some error testing. Actually not needed if you use the
// goldenRatio function right
if (ratio instanceof Error) {
b.println(ratio); // we had an error ;-|
return -1; // end that whole sketch
}
var pw = ratio.ab; // get the ratio for the whole page
var phratio = goldenRatio(null, ratio.a, null); // calc the ratio for the height
var ph = phratio.ab; // set the height
b.clear(b.doc()); // clear the current document
b.units(b.MM); // we want to print. use MM instead of default pixels
var doc = b.doc(); // a reference to the current document
// set some preferneces of the document for better handling
doc.documentPreferences.properties = {
pageWidth: pw,
pageHeight: ph
}; // set the page size
doc.viewPreferences.rulerOrigin = RulerOrigin.SPREAD_ORIGIN; // upper left corner
// ----------
// main code goes here
b.noStroke(); // we want no stroke
b.fill(255); // font color
b.textFont('Akko Rounded Pro\tThin'); // does this throw an error if the font is not present?
var r1 = b.rect(0, 0, ratio.a, ratio.a); // the first rectangle
var r2 = b.rect(ratio.a, 0, ratio.b, ratio.b); // the second rectangle
var tfa = b.text('A', ratio.a - 10, (ratio.a) - 10, 10, 10); // the text for value a
var tfb = b.text('B', ratio.ab - 10, (ratio.b) - 10, 10, 10); // text for value b
var tfab = b.text('AB', ratio.ab - 10, 5, 10, 10); // text for value ab
// the 0.25 is visual sugar to prevent a minimal white gap
var bleedfix = 0.25; // to fix bleeding
b.stroke(255); // white lines
// start the first line
b.beginShape();
b.vertex(0 - bleedfix, 0); // left
b.vertex(ratio.ab + bleedfix, 0); // right
var lineab = b.endShape(); // save it
b.beginShape(); // start the econd line
b.vertex(0 - bleedfix, ratio.a); // left
b.vertex(ratio.a + 0.25, ratio.a); // right
var linea = b.endShape(); // save it
b.beginShape(); // start the third line
b.vertex(ratio.a, ratio.b); // left
b.vertex(ratio.ab + bleedfix, ratio.b); // right
var lineb = b.endShape(); // save it
// some properties for all the lines
// also visual sugar
var props = {
strokeTint: 50,
strokeWeight: 5,
leftLineEnd: ArrowHead.BAR_ARROW_HEAD,
rightLineEnd: ArrowHead.BAR_ARROW_HEAD
};
linea.properties = props; // set it
lineb.properties = props; // set it
lineab.properties = props; // set it
r1.fillColor = doc.swatches[4]; // set the fill color for the first rectangle
r2.fillColor = doc.swatches[5]; // and the fill for the second
// ----------
// get the name, save the file and export a PNG
var fname = File($.fileName).parent.fsName + '/' + ($.fileName.split('/')[$.fileName.split('/').length - 1]).split('.')[0] + '.indd';
// b.println(fname);
doc.save(fname, false, 'basil', true);
b.savePNG('out.png');
} // end of draw
b.go(); // run it