Onwards with simple shapes in JScript
Shapes like regular triangle, square, pentagon, hexagon etc fall in that category of Regullar Convex Polygons, we can simply call them nGon (n= any value):
The Parametric n Gon challenge!
In the
link you can see a little information about the shape components
Now for a simple script that produces a n-Gon (Linear curve) will need a given 'radius' and 'n'
Then we can solve the possitions of the points within a for loop, with help from sin and cos
We also want a function that will help so we dont have trouble with radians and angles.
Code: Select all
var n = 500;
var radius = 6;
var angle = 360 / n;
function toRadians (angle) {
return angle * (Math.PI / 180);
}
var pointslist="";
for(i = 0; i <= n-1; i++) {
pointslist+="("+radius*Math.cos(toRadians(angle * i))+","+radius * Math.sin(toRadians(angle * i))+",0),";
}
pointslist=pointslist.slice(0,-1);
crv=SICreateCurve("nGon", 1, 1);
SISetCurvePoints( crv, pointslist, false );
ApplyTopoOp("CrvOpenClose", crv, i, siPersistentOperation, null);
A better version of that script could be one that logs more info:
Code: Select all
//LINEAR CURVES -REGULAR CONVEX POLYGON or N-GON (Definition with 'n' and 'radius')
var n = 7; //'N' of the NGon
var radius = 6; //RADIUS or Circumradius
//calcs
function toRadians (angle) { //receives angles returns radians
return angle * (Math.PI / 180);
}
var angle = 360 / n; //MAIN ANGLE or vertex (or apex for each isosceles Triangle )
var innerAngle=180-(360/n); //INTERNAL angle
var extAngle=180-innerAngle; //SUPPLEMENTARY angle or exterior
var hIA=innerAngle/2; //BASE ANGLE there are 2 equals in each isosceles triangle
var dCount=(n*(n-3))/2; //Possible diagonals counter
var tanDist =Math.sin(toRadians(hIA))*radius; //INRADIUS the tangent Distance from a side to the center
var sideL=2*Math.sqrt(Math.pow(radius,2)-Math.pow(tanDist,2));//SIDE LENGTH
var areaIso=tanDist*sideL/2; //AREA of each isosceles TRIANGLE
var area=areaIso*n; //TOTAL AREA OF NGON
var pointslist="";
for(i = 0; i <= n-1; i++) {
pointslist+="("+radius*Math.cos(toRadians(angle * i))+","+radius * Math.sin(toRadians(angle * i))+",0),";
}
pointslist=pointslist.slice(0,-1);
crv=SICreateCurve("nGon", 1, 1);
SISetCurvePoints( crv, pointslist, false );
ApplyTopoOp("CrvOpenClose", crv, i, siPersistentOperation, null);
SelectObj(crv, null, true);
LogMessage(
"Succesfully generated nGon with n = "+n+
"\nCircum-Radius :"+radius+
"\n\nInradius: "+tanDist+
"\nMain Angle (360°/n): "+angle+
"°\nInterior Angle: "+innerAngle+
"°\nSupplementary Angle: "+extAngle+
"°\nPossible diagonals: "+dCount+
"\nSide Lenght: "+sideL+
"\nArea of each isosceles triangle: "+areaIso+
"\nArea of nGon: "+area
);
For a real parametric challenge we should have the ability to define the shape with more than 1 cases of given parameters. We need at least one type indicator that will result to spcific 'n' and one size indicator that will result to a certain 'radius', if we have 5x5 parameters, we should normaly solve the problem 25 times! To overcome this problem with my nub scripting skillz as iI said earlir I came up with a loop that calls find_parameter() functions till problem is solved. The find functions would return same value i
f already defined or would try to solve the
undefined variables with help from something else that is potentially defined. So i had to write a bounch of relationships for each parameter. And it worked with maximum 5 loops it solved all other variables.But i will present a better case of what i did:
Next script generates an n-Gon with more than 25 combos of given values. If the n gon is REGGULAR you get a notification in LOG
Certain values (on type parameters) will result to a 'n' that corespond to no case of regular polygon then youll get an IRREGULAR notification and the result will have at least one irregular component.
For the following script i will credit my friend Spasi for converting my horible non optimized code to something that i barelly understand xD.
Code: Select all
//LINEAR CURVES -REGULAR CONVEX POLYGON or N-GON (Parametric)
//Regullar Convex Polygon or N-Gon
//Define it by at list 2 parameters that indicate type and size .
//Type indicators
var n;
var angle=10;
var innerAngle;
var extAngle;
var hIA;
//Size indicators
var radius;
var area;
var tanDist;
var sideL;
var areaIso=45;
//DEBUG
var dCount;//todo add relationship that results to a 'n'
function toRadians(angle) {
return angle * (Math.PI / 180);
}
function property(initValue, calc) {
var value = initValue;
var inCalc = false;
return function() {
if (value !== undefined) {
return value;
}
if (!inCalc) {
inCalc = true;
try {
value = calc.call(this);
} finally {
inCalc = false;
}
}
return value;
}
}
polygon = (function() {
function isRegular() {
var n = this.n();
return (n | 0) === n;
}
return {
isValid: function() {
// TODO: validate input
return this.n() !== undefined && this.angle() !== undefined && this.radius() !== undefined;
},
n: property(n, function() {
var angle = this.angle();
if (angle !== undefined) {
return 360.0 / angle;
}
return undefined;
}),
angle: property(angle, function() {
var n = this.n();
if (n !== undefined) {
return 360 / n;
}
var hIA = this.hIA();
if (hIA !== undefined) {
return 180 - 2 * hIA;
}
return undefined;
}),
hIA: property(hIA, function() {
var innerAngle = this.innerAngle();
if (innerAngle !== undefined) {
return innerAngle * 0.5;
}
return undefined;
}),
innerAngle: property(innerAngle, function() {
var n = this.n();
if (n !== undefined) {
return 180 - (360 / n);
}
var extAngle = this.extAngle();
if (extAngle !== undefined) {
return 180 - extAngle;
}
return undefined;
}),
extAngle: property(extAngle, function() {
var innerAngle = this.innerAngle();
if (innerAngle !== undefined) {
return 180 - innerAngle;
}
return undefined;
}),
radius: property(radius, function() {
var sideL = this.sideL();
var angle = this.angle();
if (sideL !== undefined && angle !== undefined) {
return (sideL * 0.5) / Math.sin(toRadians(angle * 0.5));
}
return undefined;
}),
sideL: property(sideL, function() {
var radius = this.radius();
var angle = this.angle();
if (radius !== undefined && angle !== undefined) {
return 2 * Math.sin(toRadians(angle * 0.5)) * radius
}
var tanDist = this.tanDist();
if (tanDist !== undefined && angle !== undefined) {
return 2 * tanDist * Math.tan(toRadians(angle * 0.5));
}
if (radius !== undefined && tanDist !== undefined) {
return 2 * Math.sqrt(Math.pow(radius, 2) - Math.pow(tanDist, 2));
}
return undefined;
}),
tanDist: property(tanDist, function() {
var sideL = this.sideL();
var angle = this.angle();
if (sideL !== undefined) {
return sideL / (2 * Math.tan(toRadians(angle * 0.5)));
}
var areaIso = this.areaIso();
if (areaIso !== undefined && angle !== undefined) {
return Math.sqrt(areaIso / Math.tan(toRadians(angle * 0.5)));
}
return undefined;
}),
areaIso: property(areaIso, function() {
var area = this.area();
var n = this.n();
if (area !== undefined && n !== undefined) {
return area / n;
}
var tanDist = this.tanDist();
var sideL = this.sideL();
if (tanDist !== undefined && sideL !== undefined) {
return (tanDist * sideL) * 0.5;
}
return undefined;
}),
area: property(area, function() {
var n = this.n();
var areaIso = this.areaIso();
if (n !== undefined && areaIso !== undefined) {
return n * areaIso;
}
return undefined;
}),
dCount: property(dCount, function() {
var n = this.n();
if (n !== undefined) {
return (n * (n - 3)) * 0.5;
}
return undefined;
}),
render: function() {
LogMessage(
"\nn: " + this.n() + (isRegular.call(this) ? " REGULAR" : " IRREGULAR ") +
"\nCircum-Radius: " + this.radius() +
"\nIn-Radius: " + this.tanDist() +
"\nSide Length: " + this.sideL() +
"\n\nMain Angle (360°/n): " + this.angle() + "°" +
"\nInterior Angle: " + this.innerAngle() +
"\nIntAngle/2 " + this.hIA() + "°" +
"\nExt_Angle: " + this.extAngle() +
"\n\nArea of each isosceles triangle: " + this.areaIso() +
"\nArea of nGon: " + this.area() +
"\nPossible diagonals: " + this.dCount()
);
var n = this.n();
var angle = this.angle();
var radius = this.radius();
var pointsList = "";
for (i = 0; i <= n - 1; i++) {
pointsList += "(" + radius * Math.cos(toRadians(angle * i)) + "," + radius * Math.sin(toRadians(angle * i)) + ",0),";
}
pointsList = pointsList.slice(0, -1);
return pointsList;
}
};
})();
if (polygon.isValid()) {
var pointsList = polygon.render();
//*
crv=SICreateCurve("nGon", 1, 1);
SISetCurvePoints(crv, pointsList, false);
ApplyTopoOp("CrvOpenClose", crv, i, siPersistentOperation, null);
SelectObj(crv, null, true);
//*/
}