Created
June 27, 2023 10:30
-
-
Save sttk3/fea99f9ba399e2f25dcf92f91a5264b0 to your computer and use it in GitHub Desktop.
Illustrator: calculate rotation angle at which segment becomes 27mm width
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @file calculate rotation angle at which segment becomes 27mm width | |
* @version 1.0.0 | |
* @author sttk3.com | |
* @copyright © 2023 sttk3.com | |
*/ | |
(function() { | |
// config | |
var dstWidth = 27 ; // as mm | |
if(app.documents.length <= 0) {return ;} | |
var doc = app.documents[0] ; | |
var sel = doc.selection ; | |
if(sel.length <= 0) {return ;} | |
// mm to pt | |
var adjacent = new UnitValue(dstWidth, 'mm').as('pt') ; | |
// if main item is not path item, exit | |
var mainItem = sel[0] ; | |
if(mainItem.constructor.name != 'PathItem') {return ;} | |
// get first and last anchor | |
var pathPoints = mainItem.pathPoints ; | |
var anchorLength = pathPoints.length ; | |
if(anchorLength < 2) {return ;} | |
var origin = pathPoints[0].anchor ; | |
var anchorA = pathPoints[anchorLength - 1].anchor ; | |
// get length of hypotenuse. exit if destination value is not expected to be reached | |
var hypotenuse = Math.sqrt( Math.pow(anchorA[0] - origin[0], 2) + Math.pow(anchorA[1] - origin[1], 2) ) ; | |
if(hypotenuse < adjacent) { | |
alert('Line needs to increase longer.') ; | |
return ; | |
} | |
// vector direction of destination segment | |
// adjacent: bottom width,hypotenuse: radius | |
var dstAngle0 = Math.acos(adjacent / hypotenuse) ; | |
// vector direction of current segment | |
var currentAngle = angle2(origin, anchorA) ; | |
// rotaion angle | |
var dstAngle1 = getClosestAngle(dstAngle0, currentAngle) ; | |
var rotaionAngle = getAngleDiff(dstAngle1, currentAngle) ; | |
prompt('Rotaion angle', degrees(rotaionAngle)) ; | |
})() ; | |
/** | |
* get angle from two anchor points | |
* @param {Array} p0 start point [x, y] | |
* @param {Array} p1 end point [x, y] | |
* @return {Number} angle (radians) | |
*/ | |
function angle2(p0, p1) { | |
return Math.atan2(p1[1] - p0[1], p1[0] - p0[0]) ; | |
} | |
/** | |
* get angle of minimum rotation | |
* @param {Number} dstAngle destination angle | |
* @param {Number} currentAngle src angle | |
* @return {Number} angle (radians) | |
*/ | |
function getClosestAngle(dstAngle, currentAngle) { | |
var diff1 = Math.abs(dstAngle - currentAngle) ; | |
var diff2 = Math.abs(dstAngle + Math.PI - currentAngle) ; | |
var diff3 = Math.abs(dstAngle - Math.PI - currentAngle) ; | |
var minDiff = Math.min(diff1, diff2, diff3) ; | |
if(minDiff === diff1) { | |
return dstAngle ; | |
} else if (minDiff === diff2) { | |
return dstAngle + Math.PI ; | |
} else { | |
return dstAngle - Math.PI ; | |
} | |
} | |
/** | |
* get difference between dstAngle and currentAngle | |
* @param {Number} dstAngle destination angle | |
* @param {Number} currentAngle src angle | |
* @return {Number} angle (radians) | |
*/ | |
function getAngleDiff(dstAngle, currentAngle) { | |
var difference = dstAngle - currentAngle ; | |
if(difference > Math.PI) { | |
difference -= 2 * Math.PI ; | |
} else if(difference < -Math.PI) { | |
difference += 2 * Math.PI ; | |
} | |
return difference ; | |
} | |
/** | |
* convert radians to degrees | |
* @param {Number} rad radians | |
* @return {Number} degrees | |
*/ | |
function degrees(rad) { | |
return rad * 180 / Math.PI ; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment