NSAffineTransform.shearXBy_() help

Help. I am at wit’s end, and no AI model was able to correct my (rather simple) code.

For some reason, this doesn’t shear the outlines from the specified centre:

from Foundation import NSPoint, NSAffineTransform
from math import tan, pi

def shear_point(centre, angle, point):
	transform = NSAffineTransform.new()
	transform.translateXBy_yBy_(centre.x, centre.y)
	shear = tan(angle * pi / 180.0)
	transform.shearXBy_(shear)
	transform.translateXBy_yBy_(-centre.x, -centre.y)
	transformed_point = transform.transformPoint_(point)

	return transformed_point
	
for p in Layer.paths:
	for n in p.nodes:
		n.position = shear_point(NSPoint(Layer.bounds.size.width / 2, Layer.bounds.size.height / 2), 10, n.position)

It always shears my outlines from the bottomleft origin of my outlines. Please help me understand what I’m doing wrong.

Try this:

from Foundation import NSPoint, NSAffineTransform
from math import tan, pi

def shear_point(centre, angle, point):
	transform = NSAffineTransform.new()
	shear = tan(angle * pi / 180.0)
	transform.shearXBy_atCenter_(shear, centre)
	transformed_point = transform.transformPoint_(point)
	return transformed_point
	
for p in Layer.paths:
	for n in p.nodes:
		n.position = shear_point(Layer.bounds.size.height / 2, 10, n.position)

I would do it like this:

from Foundation import NSPoint, NSAffineTransform
from math import tan, pi, radians

def shear_transform(centre, angle):
	transform = NSAffineTransform.new()
	shear = tan(radians(angle))
	transform.shearXBy_atCenter_(shear, centre)
	return transform

transform = shear_transform(Layer.bounds.size.height / 2, 10)

for p in Layer.paths:
	for n in p.nodes:
		n.position = transform.transformPoint_(n.position)
``
1 Like

You’re my hero. Thank you. I don’t understand what’s wrong with my original code, but yours works.

The problem with the centering is a problem with the “shearXBy_” method. It doesn’t handle the “external” center shift like a rotate transform would.