我想沿着圆弧(UIBezierPath)放置UICollectionViewCells。请建议计算这些细胞中心的公式。
let startAngle: Double = 0
let endAngle: Double = 180
var arcRadius: CGFloat = 414 // Actually updated dynamically when layout changes
var arcCenter: CGPoint {
get {
return CGPoint(x: contentView.bounds.width/2, y: contentView.bounds.height/2 - arcRadius)
}
}
func drawArc() {
contentView.layer.sublayers?.forEach {
if $0 is CAShapeLayer {
$0.removeFromSuperlayer()
}
}
// Create an arc
let path = UIBezierPath(arcCenter: arcCenter,
radius: arcRadius,
startAngle: degreesToRadians(value: startAngle),
endAngle: degreesToRadians(value: endAngle),
clockwise: true)
// Create a shape layer and add path
let shapeLayer = createShapeLayer()
shapeLayer.path = path.cgPath
contentView.layer.addSublayer(shapeLayer)
}
所有这些细胞具有相同的恒定大小,例如(100,100),两个细胞之间的x距离(水平)也是恒定的,比如说20。
public class Ctester {
public Ctester(){
Frame();
}
public void Frame(){
JFrame fr = new JFrame();
fr.setVisible(true);
fr.setSize(500, 500);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fr.setResizable(false);
JPanel p = new JPanel(new GridBagLayout());
ImageIcon icon = new ImageIcon(getClass().getResource("zippo.jpg"));
JLabel l = new JLabel(icon)
JButton bm1 = new JButton("hellu");
p.add(l);
p.add(bm1);
fr.add(p);
}
public static void main(String[]args){
new Ctester();
}
}
答案 0 :(得分:1)
可以使用圆的参数方程来实现。这是我的代码 -
创建一个Circle
对象,然后调用其func point(startAngle: forItemAtIndex:)
来查找这些单元格的中心点。
struct Circle {
var center: CGPoint
var radius: CGFloat
func point(startAngle: Double, forItemAtIndex index: Int) -> CGPoint {
/*
This is based on parametric equation of a circle with center (cx, cy) -
x = cx + radius*cos(angle)
y = cy + radius*sin(angle)
*/
var deltaX: CGFloat = 122 // Fixed horizontal (x) distance between 2 cells' centers
var deltaY = radius - sqrt(pow(radius, 2) - pow(deltaX, 2)) // formula to calculate vertical distance between cells' centers
var actualY = center.y + radius - deltaY
var deltaAngleRadians = asin((actualY - center.y)/radius)
var deltaAngle = radiansToDegrees(value: deltaAngleRadians)
var stepAngle: Double = deltaAngle - startAngle
var actualAngle = startAngle + (Double(index)*stepAngle)
let viewCenterX = radius * cos(degreesToRadians(value: actualAngle)) + center.x
let viewCenterY = radius * sin(degreesToRadians(value: actualAngle)) + center.y
var position = CGPoint(x: viewCenterX, y: viewCenterY)
return position
}
func bezierPath(startAngle: Double = 0, endAngle: Double = 180, clockwise: Bool = true) -> UIBezierPath {
return UIBezierPath(arcCenter: center, radius: radius, startAngle: degreesToRadians(value: startAngle), endAngle: degreesToRadians(value: endAngle), clockwise: true)
}
func degreesToRadians(value: Double) -> CGFloat {
return CGFloat(value * .pi / 180.0)
}
func radiansToDegrees(value: CGFloat) -> Double {
return Double(value * 180.0 / .pi)
}
}