gpt4 book ai didi

swift - MKOverlay 自定义描边 - CGPath

转载 作者:行者123 更新时间:2023-11-28 06:48:42 30 4
gpt4 key购买 nike

我需要自定义 MKOverlay 笔触样式。我需要在叠加层内部使用更宽更浅的颜色,就像这个笔触。

This is what I want

我知道怎么画了,

This is what I get

class PolygonRenderer:MKPolygonRenderer {

override func drawMapRect(mapRect: MKMapRect, zoomScale: MKZoomScale, inContext context: CGContext) {

let fullPath = CGPathCreateMutable()

for i in 0 ..< self.polygon.pointCount {

let point = self.pointForMapPoint(self.polygon.points()[i])

print(point)

if i == 0 {

CGPathMoveToPoint(fullPath, nil, point.x, point.y)

} else {

CGPathAddLineToPoint(fullPath, nil, point.x, point.y)
}
}

let baseWidth = 10 / zoomScale

CGContextAddPath(context, self.path)

CGContextSetStrokeColorWithColor(context, UIColor.blueColor().colorWithAlphaComponent(0.3).CGColor)

CGContextSetLineWidth(context, baseWidth * 2)

CGContextSetLineCap(context, self.lineCap)

CGContextStrokePath(context);

CGContextAddPath(context, self.path)

CGContextSetStrokeColorWithColor(context, UIColor.blueColor().CGColor)

CGContextSetLineWidth(context, baseWidth)

CGContextSetLineCap(context, self.lineCap)

CGContextStrokePath(context)
}
}

是否可以像第一张图那样画出路径?

最佳答案

对于所有可能觉得这个问题有用的人,我自己找到了一种方法。此过程适用于仅包含点的 CGPath,即它不包含弧。所以这是我创建的 MKPolygonRender 子类。

这些扩展来自 here谢谢 Logan

import UIKit
import MapKit


extension CGPoint {
func angleToPoint(comparisonPoint: CGPoint) -> CGFloat {
let originX = comparisonPoint.x - self.x
let originY = comparisonPoint.y - self.y
let bearingRadians = atan2f(Float(originY), Float(originX))
var bearingDegrees = CGFloat(bearingRadians).degrees
while bearingDegrees < 0 {
bearingDegrees += 360
}
return (bearingDegrees + 270).truncatingRemainder(dividingBy: 360)
}
}

extension CGFloat {
var degrees: CGFloat {
return self * CGFloat(180.0 / M_PI)
}
}

class PolygonRenderer: MKPolygonRenderer {

override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {

let strokeWidth = MKRoadWidthAtZoomScale(zoomScale) * self.lineWidth

let outerPath = CGMutablePath()
let innerPath = CGMutablePath()

var previousPoint = point(for: self.polygon.points()[self.polygon.pointCount - 1])

for i in 0 ..< self.polygon.pointCount {

let currentPoint = point(for: self.polygon.points()[i])

let nextPoint:CGPoint = point(for: self.polygon.points()[(i + 1) % self.polygon.pointCount])

let a : CGFloat = {

let lengthA = distance(currentPoint, b: nextPoint)
let lengthB = distance(previousPoint, b: currentPoint)
let lengthC = distance(nextPoint, b: previousPoint)

return CGFloat(Int(round(Double(angle(lengthA, b: lengthB, c: lengthC)))))

}()

let degrees = previousPoint.angleToPoint(comparisonPoint: currentPoint)

let strokeHyp: CGFloat = CGFloat(strokeWidth) / CGFloat(sind(Double(a) / 2))

var newPoint = CGPoint()

newPoint.x = CGFloat(Double(strokeHyp) * cos(degreesToRadians(Double(degrees + (360 - (a / 2))).truncatingRemainder(dividingBy: 360)))) + currentPoint.x
newPoint.y = CGFloat(Double(strokeHyp) * sin(degreesToRadians(Double(degrees + (360 - (a / 2))).truncatingRemainder(dividingBy: 360)))) + currentPoint.y

print("stroke width: ", strokeWidth, "stroke hyp: ", strokeHyp)

print("pointIndex: ", i,"dir: ", degrees)

if i == 0 {
outerPath.move(to: currentPoint)
innerPath.move(to: newPoint)
} else {
outerPath.addLine(to: currentPoint)
innerPath.addLine(to: newPoint)
}

previousPoint = currentPoint
}

outerPath.closeSubpath()

context.addPath(outerPath)

context.setLineWidth(strokeWidth)

context.setStrokeColor(self.strokeColor?.cgColor ?? UIColor.black.cgColor)

context.strokePath()


innerPath.closeSubpath()

context.addPath(innerPath)

context.setLineWidth(strokeWidth)

context.setStrokeColor(self.strokeColor?.withAlphaComponent(0.3).cgColor ?? UIColor.black.withAlphaComponent(0.3).cgColor)

context.strokePath()

}

func angle(_ a:CGFloat, b:CGFloat, c:CGFloat) -> CGFloat {

var angle = (a * a) + (b * b) - (c * c)

angle = angle / (2 * a * b)

return CGFloat(radiansToDegrees(acos(Double(angle))))
}

func distance(_ a:CGPoint,b:CGPoint)->CGFloat{
return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2));
}

func direction(_ center:CGPoint,point:CGPoint)->CGFloat{

let hyp = Double(distance(center, b: point))
let adj = Double(center.y - point.y)
var angle = CGFloat(radiansToDegrees(asin(adj/hyp)))

if point.x < center.x {
angle += 180
} else {
angle = 360 - angle
}
return round(angle)
}

func radiansToDegrees(_ radians:Double)->Double{
return (radians * 180.0 / Double.pi)
}

func degreesToRadians(_ degrees:Double)->Double{
return ((degrees - 90) * Double.pi / 180.0)
}

func sind(_ degrees: Double) -> Double {
return __sinpi(degrees/180.0)
}
}

This is an example of this PolygonRenderer

关于swift - MKOverlay 自定义描边 - CGPath,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35517292/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com