Предистория
Под впечатлением статей про Sprite Kit и про GestureRecognizer возникла идея портировать простенькое приложение себе на телефон. А так как там достаточно часто используются структуры CGPoint, то озадачился изучением перегрузки операторов в Swift и подсмотрел тут.
Реализация
В несколько шагов создал себе некоторую «библиотеку» операторов перегрузки для удобной работы с выражениями для структур CGPoint. Заодно на каждом шаге потестировал тестирование в XCode.
Фактически реализована полная алгебра операций для линейного пространства векторов (структуры CGPoint), скаляров (CGFloat) и частично операторов (CGAffineTransform).
Так как, данные функции перегрузки операторов описаны глобально, то функционал добавляется в любой проект легко — через добавление исходника.
Конечно, примеров использования перегрузки на вымышленных ситуациях достаточно много, но данная «библиотека операторов» возможно окажется:
- чуть более конкретным примером,
- готовым решением, дающим экономии пары часов рутинного набора и отладки простейшего кода (листинг исходника целиком приведен в конце).
Шаг за шагом
func +(left: CGPoint, right: CGPoint)->CGPoint{ return CGPoint(x: left.x+right.x, y: left.y+right.y) } prefix func -(right: CGPoint)->CGPoint{ return CGPoint(x: -right.x, y: -right.y) } func -(left: CGPoint, right: CGPoint)->CGPoint{ return left + (-right) }
func *(left: CGPoint, right: CGFloat)->CGPoint{ return CGPoint(x: left.x*right, y: left.y*right) } func *(left: CGFloat, right: CGPoint)->CGPoint{ return right*left } func /(left: CGPoint, right: CGFloat)->CGPoint{ return left*(1/right) }
func +=(inout left:CGPoint, right:CGPoint){ left = left+right } func -=(inout left:CGPoint, right:CGPoint){ left = left-right } func *=(inout left:CGPoint, right:CGFloat){ left = left*right } func /=(inout left:CGPoint, right:CGFloat){ left = left/right }
func *(left: CGPoint, right: CGPoint)->CGFloat{ return left.x*right.x + left.y*right.y } func ^(left: CGPoint, right: CGPoint)->CGFloat{ return left.x*right.y - left.y*right.x }
func *(left: CGPoint, right: CGAffineTransform)->CGPoint{ return CGPointApplyAffineTransform(left, right) } func *=(inout left:CGPoint, right:CGAffineTransform){ left = left*right }
func *(left: CGAffineTransform, right: CGAffineTransform)->CGAffineTransform{ return CGAffineTransformConcat(left, right) } func *=(inout left:CGAffineTransform, right:CGAffineTransform){ left = left*right }
Заключение
Приведенный пример являет необходимым и достаточным набором в текущем понимании моих потребностей. В частности, поэтому не реализована алгебра для матриц и для аналогичных структур (напр., CGSize).
Хочется отметить еще, что данные решения являются настолько очевидными и удобными, что будет неудивительным, если со временем подобная перегрузка войдет как часть стандартной библиотеки CoreGraphics.
import Foundation func +(left: CGPoint, right: CGPoint)->CGPoint{ return CGPoint(x: left.x+right.x, y: left.y+right.y) } prefix func -(right: CGPoint)->CGPoint{ return CGPoint(x: -right.x, y: -right.y) } func -(left: CGPoint, right: CGPoint)->CGPoint{ return left + (-right) } /////////////////////////////////////////////////// func *(left: CGPoint, right: CGFloat)->CGPoint{ return CGPoint(x: left.x*right, y: left.y*right) } func *(left: CGFloat, right: CGPoint)->CGPoint{ return right*left } func /(left: CGPoint, right: CGFloat)->CGPoint{ return left*(1/right) } /////////////////////////////////////////////////// func +=(inout left:CGPoint, right:CGPoint){ left = left+right } func -=(inout left:CGPoint, right:CGPoint){ left = left-right } func *=(inout left:CGPoint, right:CGFloat){ left = left*right } func /=(inout left:CGPoint, right:CGFloat){ left = left/right } /////////////////////////////////////////////////// /////////////////////////////////////////////////// func *(left: CGPoint, right: CGPoint)->CGFloat{ return left.x*right.x + left.y*right.y } func /(left: CGPoint, right: CGPoint)->CGFloat{ return left.x*right.y - left.y*right.x } /////////////////////////////////////////////////// /////////////////////////////////////////////////// func *(left: CGPoint, right: CGAffineTransform)->CGPoint{ return CGPointApplyAffineTransform(left, right) } func *=(inout left:CGPoint, right:CGAffineTransform){ left = left*right } /////////////////////////////////////////////////// func *(left: CGAffineTransform, right: CGAffineTransform)->CGAffineTransform{ return CGAffineTransformConcat(left, right) } func *=(inout left:CGAffineTransform, right:CGAffineTransform){ left = left*right }
ссылка на оригинал статьи http://habrahabr.ru/post/271647/
Добавить комментарий