ROUND CORNER

 

This script is using the Scriptographer pen tool to round any straight corner clicked on by the user. The corners radii can be represented in units of points, inches, milimeters, centimeters and picas. It does, however, NOT work on beziérs or curved paths. For that you could use the Round Any Corner AI script by Hiroyuki, and while your at it, be sure to check out his blog – Lines About To Be Generated as he has some nice Sg stuff there.

USAGE: Set desired radius and unit and click any straight corner. If the set radius is too big to fit, two options are available. Either adjust the radius to a smaller value that fits manually, or use the Force Smaller Radius-option, it will calculate the radius to an exact fit.

The second checkbox makes the script round corners with the largest radius possible.

function onMouseDown(event) {
    var hitResult = document.hitTest(event.point, 'anchors')
    if(hitResult){
    	roundCorner(hitResult, values.radius * unitMultiplier[values.units], values.comp, values.makeBig)
    }
}

function roundCorner(obj, rad, largestPossible, radOrLg){
  		var selectedSegment = obj.segment
		var segmentIndex = selectedSegment.index

		var vector1 = selectedSegment.point - selectedSegment.previous.point
		var vector2 = selectedSegment.point - selectedSegment.next.point
		var shortestVector = Math.min(vector1.length, vector2.length)

		var angle = vector1.getDirectedAngle(vector2) / 2
		var largestRadiusPossible = shortestVector * Math.tan(angle.toRadians())
		var radius = radOrLg ? largestRadiusPossible : rad

		var tangentLength = Math.abs(radius / Math.tan(angle.toRadians()))

		if(tangentLength > shortestVector){
			if(largestPossible || radOrLg){
				tangentLength = shortestVector
				radius = largestRadiusPossible
			} else {
				console.log('*** ERROR ***\nRadius too big.\nLargest possible radius is:\n    ' +
					Math.abs(largestRadiusPossible / unitMultiplier[values.units]) + '\nOptions:' +
					'\n  * Adjust radius' +
					'\n  * Check \'Force Smaller Radius\'-option' +
					'\n  * Check \'Largest Possible\'-option' +
					'\n--------------\n')
				return			
			}
		}
		console.log('*** NOTICE ***\nApplied radius is:\n    ' + Math.abs(radius / unitMultiplier[values.units]) + '\n--------------\n')

		var tangentPoint1 = selectedSegment.point - new Point({length: tangentLength, angle: vector1.angle})
		var tangentPoint2 = selectedSegment.point - new Point({length: tangentLength, angle: vector2.angle})
		var throughPoint = selectedSegment.point - new Point({length: radius / Math.sin(angle.toRadians()) + (angle < 0 ? radius : -radius), angle: vector1.angle - angle})
		var arc = new Path.Arc(tangentPoint1, throughPoint, tangentPoint2)

		for(var i = 0; i < arc.segments.length; i++){
			obj.item.insert(segmentIndex + i, arc.segments[i])
		}

		obj.item.remove(segmentIndex + arc.segments.length)
		arc.remove()
}

var unitOptions = [
	'point',
	'inch',
	'mm',
	'cm',
	'pica'
]

var unitMultiplier = {
	'point': 1,
	'inch': 72,
	'mm': 2.83465,
	'cm': 28.3465,
	'pica': 12
}

var values = {
	radius: 10,
	units: unitOptions[0],
	comp: false,
	makeBig: false,
}

var comps = {
	radius:	{type: 'number', label: 'Radius', steppers: true, min: 0.1},
	units: {type: 'list', label: 'Unit', options: unitOptions},
	comp: {type: 'boolean', label: 'Force Smaller Radius'},
	makeBig: {type: 'boolean', label: 'Largest Possible', onChange: function(value){
			comps.radius.enabled = !value
			comps.comp.enabled = !value
	}},
}

var palette = new Palette('Round Corner v1.0', comps, values)

Although, I have come up with a rather quick way of rounding any corner – even beziérs – manually. Just offset the path by the the desired radius value and then make a circle the size of double the radius with its center on the corner of the offset path. Just like this, can you dig it?

Back to scripts