使用Quartz 2D,我们可以在x
,y
和z
轴上转换视图。
在某些情况下,我们甚至可以通过更改矩阵的值来使它们看起来像3D。
我想知道是否可以将视图转换为圆柱形状,如下图所示?
请忽略气缸的顶部。我更好奇地知道是否有可能像图像中那样扭曲UIView
像圆柱体一样。
这可能只使用Quartz 2D,图层和转换(不是OpenGL)吗?如果没有,是否有可能至少在CGContext
中绘制它以使视图看起来像这样?
答案 0 :(得分:4)
你绝对不能通过变换做到这一点。您可以做的是在屏幕外创建UIView,获取视图的上下文,从中获取图像,然后使用非线性映射将图像映射到新图像。
所以:
这些步骤都不是特别困难,您可能会想出各种简化方法。例如,如果没有进行透视变换,只需渲染原始视图的条带,根据圆的坐标偏移Y坐标。
如果您希望视图实际上是交互式的,那么在处理触摸事件时您需要以相反的方向进行转换。
答案 1 :(得分:3)
不,您无法使用转换弯曲视图。
变换只能操纵视图的四个角,所以无论你做什么,它仍然是一个平面。
答案 2 :(得分:2)
我意识到这超出了Quartz2D ...您可以尝试添加SceneKit。
答案 3 :(得分:1)
参考:Using OpenGL ES 2.0 with iOS, how do I draw a cylinder between two points?
我也为我的一个项目使用了相同的代码:
检查提到它的地方以绘制cone shape;它已经过时了但是在适应算法后,它可以工作。
请参阅以下代码以获取解决方案。 Self表示网格,包含顶点,索引等。
- (instancetype)initWithOriginRadius:(CGFloat)originRadius
atOriginPoint:(GLKVector3)originPoint
andEndRadius:(CGFloat)endRadius
atEndPoint:(GLKVector3)endPoint
withPrecision:(NSInteger)precision
andColor:(GLKVector4)color
{
self = [super init];
if (self) {
// normal pointing from origin point to end point
GLKVector3 normal = GLKVector3Make(originPoint.x - endPoint.x,
originPoint.y - endPoint.y,
originPoint.z - endPoint.z);
// create two perpendicular vectors - perp and q
GLKVector3 perp = normal;
if (normal.x == 0 && normal.z == 0) {
perp.x += 1;
} else {
perp.y += 1;
}
// cross product
GLKVector3 q = GLKVector3CrossProduct(perp, normal);
perp = GLKVector3CrossProduct(normal, q);
// normalize vectors
perp = GLKVector3Normalize(perp);
q = GLKVector3Normalize(q);
// calculate vertices
CGFloat twoPi = 2 * PI;
NSInteger index = 0;
for (NSInteger i = 0; i < precision + 1; i++) {
CGFloat theta = ((CGFloat) i) / precision * twoPi; // go around circle and get points
// normals
normal.x = cosf(theta) * perp.x + sinf(theta) * q.x;
normal.y = cosf(theta) * perp.y + sinf(theta) * q.y;
normal.z = cosf(theta) * perp.z + sinf(theta) * q.z;
AGLKMeshVertex meshVertex;
AGLKMeshVertexDynamic colorVertex;
// top vertex
meshVertex.position.x = endPoint.x + endRadius * normal.x;
meshVertex.position.y = endPoint.y + endRadius * normal.y;
meshVertex.position.z = endPoint.z + endRadius * normal.z;
meshVertex.normal = normal;
meshVertex.originalColor = color;
// append vertex
[self appendVertex:meshVertex];
// append color vertex
colorVertex.colors = color;
[self appendColorVertex:colorVertex];
// append index
[self appendIndex:index++];
// bottom vertex
meshVertex.position.x = originPoint.x + originRadius * normal.x;
meshVertex.position.y = originPoint.y + originRadius * normal.y;
meshVertex.position.z = originPoint.z + originRadius * normal.z;
meshVertex.normal = normal;
meshVertex.originalColor = color;
// append vertex
[self appendVertex:meshVertex];
// append color vertex
[self appendColorVertex:colorVertex];
// append index
[self appendIndex:index++];
}
// draw command
[self appendCommand:GL_TRIANGLE_STRIP firstIndex:0 numberOfIndices:self.numberOfIndices materialName:@""];
}
return self;
}