为用户创建的给定行创建行扩展
Create line extensions for given line created by user
我一直在开发一个应用程序,我必须捕捉用户的触摸并在屏幕上画一条线。到目前为止这是有效的。
问题是我想为从 start/end 行到屏幕边界的那条线创建某种扩展。扩展与主线对齐很重要。
几天来我一直在努力实现这一目标,但没有取得积极成果。我的想法是使用某种线性方程来表示直线,然后创建位于直线和屏幕边界上的两个点。我遇到的第一个问题是垂直线。
y = m * x + b
slope = (y2 - y2)/(x2 - x1)
y_intercept = b = y - m * x
用户还可以在任何方向和方位创建线条。
我尝试使用这些方程式来查找任意点(x = 0、y = 0、x = 320、y = 480),但我遇到了一些奇怪的问题,如下图所示。
a) 线条确实超出了屏幕的限制。这导致应用程序几乎崩溃。
b) 我也无法确定如何 link 每个新点与当前接触点。
代码
import Foundation
import UIKit
public class TestView : UIView
{
var lineLayer : CAShapeLayer?
var lineExtensionALayer : CAShapeLayer?
var lineExtensionBLayer : CAShapeLayer?
var startPoint : CGPoint?
var endPoint : CGPoint?
override init(frame: CGRect){
super.init(frame:frame)
self.backgroundColor = UIColor.clearColor()
self.lineLayer = self.createLine(color: UIColor.redColor())
self.lineExtensionALayer = self.createLine(color: UIColor.greenColor())
self.lineExtensionBLayer = self.createLine(color: UIColor.blueColor())
}
required public init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch : UITouch = touches.first as! UITouch
let position = touch.locationInView(self)
self.startPoint = position
}
public override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
}
public override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
}
public override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch : UITouch = touches.first as! UITouch
let position = touch.locationInView(self)
self.endPoint = position
self.updateLine()
}
func createLine(color selectedColor : UIColor) -> CAShapeLayer
{
let line = CAShapeLayer()
line.frame = self.bounds
line.strokeColor = selectedColor.CGColor
line.fillColor = nil
line.lineWidth = 2
self.layer.addSublayer(line)
return line
}
func drawLine(line lineToDraw : CAShapeLayer,start pointA : CGPoint, end pointB : CGPoint)
{
let path = UIBezierPath()
path.moveToPoint(pointA)
path.addLineToPoint(pointB)
lineToDraw.path = path.CGPath
}
func updateLine(){
var line = LineFunction(point1: self.startPoint!, point2: self.endPoint!)
// Draw main line.
self.drawLine(line: self.lineLayer!, start: self.startPoint!, end: self.endPoint!)
}
}
取自 this answer,翻译成 swift 并稍作改动:
func getLines(xmin: CGFloat, ymin: CGFloat, xmax: CGFloat, ymax: CGFloat, x1: CGFloat, x2: CGFloat, y1: CGFloat, y2: CGFloat) -> (CGPoint, CGPoint) {
if y1 == y2 {
return (CGPoint(x: xmin, y: y1), CGPoint(x: xmax, y: y1))
}
if x1 == x2 {
return (CGPoint(x: x1, y: ymin), CGPoint(x: x1, y: ymax))
}
let y_for_xmin = y1 + (y2 - y1) * (xmin - x1) / (x2 - x1)
let y_for_xmax = y1 + (y2 - y1) * (xmax - x1) / (x2 - x1)
let x_for_ymin = x1 + (x2 - x1) * (ymin - y1) / (y2 - y1)
let x_for_ymax = x1 + (x2 - x1) * (ymax - y1) / (y2 - y1)
if ymin <= y_for_xmin && y_for_xmin <= ymax {
if xmin <= x_for_ymax && x_for_ymax <= xmax {
return (CGPoint(x: xmin, y: y_for_xmin), CGPoint(x: x_for_ymax, y: ymax))
}
if xmin <= x_for_ymin && x_for_ymin <= xmax {
return (CGPoint(x: xmin, y: y_for_xmin), CGPoint(x: x_for_ymin, y: ymin))
}
return (CGPoint(x: xmin, y: y_for_xmin), CGPoint(x: xmax, y: y_for_xmax))
}
if ymin <= y_for_xmax && y_for_xmax <= ymax {
if xmin <= x_for_ymin && x_for_ymin <= xmax {
return (CGPoint(x: x_for_ymin, y: ymin), CGPoint(x: xmax, y: y_for_xmax))
}
if xmin <= x_for_ymax && x_for_ymax <= xmax {
return (CGPoint(x: x_for_ymax, y: ymax), CGPoint(x: xmax, y: y_for_xmax))
}
return (CGPoint(x: xmin, y: y_for_xmin), CGPoint(x: xmax, y: y_for_xmax))
}
return (CGPoint(x: x_for_ymin, y: ymin), CGPoint(x: x_for_ymax, y: ymax))
}
func updateLine(){
let x1 = self.startPoint!.x
let x2 = self.endPoint!.x
let y1 = self.startPoint!.y
let y2 = self.endPoint!.y
let (start, end) = getLines(0, ymin: 0, xmax: bounds.width, ymax: bounds.height, x1: x1, x2: x2, y1: y1, y2: y2)
print(start, appendNewline: false)
print(" - ", appendNewline: false)
print(end)
// Draw main line.
self.drawLine(line: self.lineLayer!, start: start, end: end)
}
不幸的是,这还没有完全发挥作用,因为在一半的情况下,returned if-construct for returning 正确的扩展行不是 return 任何有用的东西。我会尝试现在或明天解决这个问题。
但它应该能让你入门
编辑:如果起点和终点都在水平轴或垂直轴上,则似乎不起作用。如果它们在不同的轴上,它会起作用。
在我添加了另外三个 return 语句之后,代码现在功能齐全:)
如果您查看记录的信息,您会发现绘制的线实际上恰好延伸到边界,而不是更远。
我一直在开发一个应用程序,我必须捕捉用户的触摸并在屏幕上画一条线。到目前为止这是有效的。
问题是我想为从 start/end 行到屏幕边界的那条线创建某种扩展。扩展与主线对齐很重要。
几天来我一直在努力实现这一目标,但没有取得积极成果。我的想法是使用某种线性方程来表示直线,然后创建位于直线和屏幕边界上的两个点。我遇到的第一个问题是垂直线。
y = m * x + b
slope = (y2 - y2)/(x2 - x1)
y_intercept = b = y - m * x
用户还可以在任何方向和方位创建线条。
我尝试使用这些方程式来查找任意点(x = 0、y = 0、x = 320、y = 480),但我遇到了一些奇怪的问题,如下图所示。
a) 线条确实超出了屏幕的限制。这导致应用程序几乎崩溃。
b) 我也无法确定如何 link 每个新点与当前接触点。
代码
import Foundation
import UIKit
public class TestView : UIView
{
var lineLayer : CAShapeLayer?
var lineExtensionALayer : CAShapeLayer?
var lineExtensionBLayer : CAShapeLayer?
var startPoint : CGPoint?
var endPoint : CGPoint?
override init(frame: CGRect){
super.init(frame:frame)
self.backgroundColor = UIColor.clearColor()
self.lineLayer = self.createLine(color: UIColor.redColor())
self.lineExtensionALayer = self.createLine(color: UIColor.greenColor())
self.lineExtensionBLayer = self.createLine(color: UIColor.blueColor())
}
required public init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch : UITouch = touches.first as! UITouch
let position = touch.locationInView(self)
self.startPoint = position
}
public override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
}
public override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
}
public override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch : UITouch = touches.first as! UITouch
let position = touch.locationInView(self)
self.endPoint = position
self.updateLine()
}
func createLine(color selectedColor : UIColor) -> CAShapeLayer
{
let line = CAShapeLayer()
line.frame = self.bounds
line.strokeColor = selectedColor.CGColor
line.fillColor = nil
line.lineWidth = 2
self.layer.addSublayer(line)
return line
}
func drawLine(line lineToDraw : CAShapeLayer,start pointA : CGPoint, end pointB : CGPoint)
{
let path = UIBezierPath()
path.moveToPoint(pointA)
path.addLineToPoint(pointB)
lineToDraw.path = path.CGPath
}
func updateLine(){
var line = LineFunction(point1: self.startPoint!, point2: self.endPoint!)
// Draw main line.
self.drawLine(line: self.lineLayer!, start: self.startPoint!, end: self.endPoint!)
}
}
取自 this answer,翻译成 swift 并稍作改动:
func getLines(xmin: CGFloat, ymin: CGFloat, xmax: CGFloat, ymax: CGFloat, x1: CGFloat, x2: CGFloat, y1: CGFloat, y2: CGFloat) -> (CGPoint, CGPoint) {
if y1 == y2 {
return (CGPoint(x: xmin, y: y1), CGPoint(x: xmax, y: y1))
}
if x1 == x2 {
return (CGPoint(x: x1, y: ymin), CGPoint(x: x1, y: ymax))
}
let y_for_xmin = y1 + (y2 - y1) * (xmin - x1) / (x2 - x1)
let y_for_xmax = y1 + (y2 - y1) * (xmax - x1) / (x2 - x1)
let x_for_ymin = x1 + (x2 - x1) * (ymin - y1) / (y2 - y1)
let x_for_ymax = x1 + (x2 - x1) * (ymax - y1) / (y2 - y1)
if ymin <= y_for_xmin && y_for_xmin <= ymax {
if xmin <= x_for_ymax && x_for_ymax <= xmax {
return (CGPoint(x: xmin, y: y_for_xmin), CGPoint(x: x_for_ymax, y: ymax))
}
if xmin <= x_for_ymin && x_for_ymin <= xmax {
return (CGPoint(x: xmin, y: y_for_xmin), CGPoint(x: x_for_ymin, y: ymin))
}
return (CGPoint(x: xmin, y: y_for_xmin), CGPoint(x: xmax, y: y_for_xmax))
}
if ymin <= y_for_xmax && y_for_xmax <= ymax {
if xmin <= x_for_ymin && x_for_ymin <= xmax {
return (CGPoint(x: x_for_ymin, y: ymin), CGPoint(x: xmax, y: y_for_xmax))
}
if xmin <= x_for_ymax && x_for_ymax <= xmax {
return (CGPoint(x: x_for_ymax, y: ymax), CGPoint(x: xmax, y: y_for_xmax))
}
return (CGPoint(x: xmin, y: y_for_xmin), CGPoint(x: xmax, y: y_for_xmax))
}
return (CGPoint(x: x_for_ymin, y: ymin), CGPoint(x: x_for_ymax, y: ymax))
}
func updateLine(){
let x1 = self.startPoint!.x
let x2 = self.endPoint!.x
let y1 = self.startPoint!.y
let y2 = self.endPoint!.y
let (start, end) = getLines(0, ymin: 0, xmax: bounds.width, ymax: bounds.height, x1: x1, x2: x2, y1: y1, y2: y2)
print(start, appendNewline: false)
print(" - ", appendNewline: false)
print(end)
// Draw main line.
self.drawLine(line: self.lineLayer!, start: start, end: end)
}
不幸的是,这还没有完全发挥作用,因为在一半的情况下,returned if-construct for returning 正确的扩展行不是 return 任何有用的东西。我会尝试现在或明天解决这个问题。
但它应该能让你入门
编辑:如果起点和终点都在水平轴或垂直轴上,则似乎不起作用。如果它们在不同的轴上,它会起作用。
在我添加了另外三个 return 语句之后,代码现在功能齐全:)
如果您查看记录的信息,您会发现绘制的线实际上恰好延伸到边界,而不是更远。