Я не могу понять, почему принятый ответ добавляет некоторую сложную логику близкого пути (возможно, это необходимо при некоторых обстоятельствах), но для тех, кому просто нужно девственное преобразование пути, здесь очищена версия этого кода, реализованная как обычный метод:
- (CGMutablePathRef)CGPathFromPath:(NSBezierPath *)path
{
CGMutablePathRef cgPath = CGPathCreateMutable();
NSInteger n = [path elementCount];
for (NSInteger i = 0; i < n; i++) {
NSPoint ps[3];
switch ([path elementAtIndex:i associatedPoints:ps]) {
case NSMoveToBezierPathElement: {
CGPathMoveToPoint(cgPath, NULL, ps[0].x, ps[0].y);
break;
}
case NSLineToBezierPathElement: {
CGPathAddLineToPoint(cgPath, NULL, ps[0].x, ps[0].y);
break;
}
case NSCurveToBezierPathElement: {
CGPathAddCurveToPoint(cgPath, NULL, ps[0].x, ps[0].y, ps[1].x, ps[1].y, ps[2].x, ps[2].y);
break;
}
case NSClosePathBezierPathElement: {
CGPathCloseSubpath(cgPath);
break;
}
default: NSAssert(0, @"Invalid NSBezierPathElement");
}
}
return cgPath;
}
Btw, мне это нужно для реализации метода «NSBezierPath stroke содержит точку».
I 'look for this conversion to call CGPathCreateCopyByStrokingPath()
, который преобразует контур штриховки NSBezierPath
в обычный путь, так что вы также можете тестировать хиты при ударах, и вот решение:
// stroke (0,0) to (10,0) width 5 --> rect (0, -2.5) (10 x 5)
NSBezierPath *path = [[NSBezierPath alloc] init];
[path moveToPoint:NSMakePoint(0.0, 0.0)];
[path lineToPoint:NSMakePoint(10.0, 0.0)];
[path setLineWidth:5.0];
CGMutablePathRef cgPath = [self CGPathFromPath:path];
CGPathRef strokePath = CGPathCreateCopyByStrokingPath(cgPath, NULL, [path lineWidth], [path lineCapStyle],
[path lineJoinStyle], [path miterLimit]);
CGPathRelease(cgPath);
NSLog(@"%@", NSStringFromRect(NSRectFromCGRect(CGPathGetBoundingBox(strokePath))));
// {{0, -2.5}, {10, 5}}
CGPoint point = CGPointMake(1.0, 1.0);
BOOL hit = CGPathContainsPoint(strokePath, NULL, point, (bool)[path windingRule]);
NSLog(@"%@: %@", NSStringFromPoint(NSPointFromCGPoint(point)), (hit ? @"yes" : @"no"));
// {1, 1}: yes
CGPathRelease(strokePath);
Это аналогично QPainterPathStroker
из Qt, но для NSBezierPath
.
In [3]: x = np.array([[1, 2], [2, 3]]
In [4]: y = np.array([[3], [4]])
In [9]: z = np.hstack([x, y])
In [10]: z
Out[10]:
array([[1, 2, 3],
[2, 3, 4]])
In [11]: z[:,:1]
array([[1],
[2]])
Вы можете использовать numpy.hstack
:
>>> import numpy as np
>>> a = np.array([[1,2], [2,3]])
>>> b = np.array([[3], [4]])
>>> np.hstack((a,b))
array([[1, 2, 3],
[2, 3, 4]])
Удаление еще проще, просто срез:
>>> c = a[:,:1]
array([[1],
[2]])
Существует метод numpy.concatenate
import numpy as np
np.concatenate( [ np.array( [ [1,2], [2,3] ] ), np.array( [ [3],[4] ] ) ] , axis = 1)
или просто используйте hstack
или vstack
np.hstack( [ np.array( [ [1,2], [2,3] ] ), np.array( [ [3],[4] ] ) ] )
. Это могут быть также используется для удаления столбца (объединить два подмассива) - это можно использовать для удаления многих столбцов.
Чтобы удалить i-й столбец, вы можете взять подмассивы в этот столбец, а затем со следующего и объединить их. Например, чтобы удалить второй столбец (index 1
):
a - np.array( [ [1,2,3], [2,3,4] ] )
a1= a[:,:1]
a2= a[:,2:]
np.hstack([a1,a2])
, поэтому вообще
def remove_column( a, i ):
return np.hstack( [a[:,:i], a[:,(i+1):] ] )
, а затем
>>> remove_column(a, 1)
array([[1, 3],
[2, 4]])
>>> remove_column(a, 0)
array([[2, 3],
[3, 4]])
Фактически , как указано в комментарии - numpy реализует свой собственный delete
метод
np.delete(a, 1, 1)
удаленный второй столбец
и удаление нескольких из них можно выполнить с помощью
np.delete(a, [column1, columne2, ..., columnK], 1)
Третий аргумент - спецификатор оси, 0
будет означать строки, 1
столбцы, None
выравнивает весь массив