菜鸟教程小白 发表于 2022-12-13 09:29:29

ios - 为用户创建的给定线路创建线路扩展


                                            <p><p>我一直在开发一个应用程序,我必须捕捉用户的触摸并在屏幕上画一条线。到目前为止,这是有效的。</p>

<p> <a href="/image/80EF0.png" rel="noreferrer noopener nofollow"><img src="/image/80EF0.png" alt="current implementation"/></a> </p>

<p>问题是我想为从行开始/结束到屏幕边界的那条线创建某种扩展。扩展名必须与主线对齐。</p>

<p> <a href="/image/UOCCV.png" rel="noreferrer noopener nofollow"><img src="/image/UOCCV.png" alt="expected implementation"/></a> </p>

<p>我这几天一直在努力实现这一目标,但没有取得积极成果。我的想法是使用某种线性方程来表示线条,然后在线条和屏幕边界上创建两个点。我遇到的第一个问题是垂直线。</p>

<pre><code>y = m * x + b
slope = (y2 - y2)/(x2 - x1)
y_intercept = b = y - m * x
</code></pre>

<p>用户还可以在任何方向和方向上创建线条。
<a href="/image/8BSma.png" rel="noreferrer noopener nofollow"><img src="/image/8BSma.png" alt="problem 1/3"/></a> </p>

<p>我尝试使用这些方程来找到任意点(x = 0,y = 0,x = 320,y = 480),但我遇到了一些奇怪的问题,如下图所示。</p>

<p>a) 线条确实超出了屏幕的限制。这导致应用程序几乎崩溃。
<a href="/image/59NYF.png" rel="noreferrer noopener nofollow"><img src="/image/59NYF.png" alt="problem 2/3"/></a> </p>

<p>b) 我也无法确定如何将每个新点与当前接触点联系起来。
<a href="/image/z7nWd.png" rel="noreferrer noopener nofollow"><img src="/image/z7nWd.png" alt="problem 3/3"/></a> </p>

<p>代码</p>

<pre><code>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(&#34;init(coder:) has not been implemented&#34;)
    }

    public override func touchesBegan(touches: Set&lt;NSObject&gt;, withEvent event: UIEvent) {
      let touch : UITouch = touches.first as! UITouch
      let position = touch.locationInView(self)

      self.startPoint = position
    }

    public override func touchesCancelled(touches: Set&lt;NSObject&gt;!, withEvent event: UIEvent!) {

    }

    public override func touchesEnded(touches: Set&lt;NSObject&gt;, withEvent event: UIEvent) {

    }

    public override func touchesMoved(touches: Set&lt;NSObject&gt;, 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) -&gt; 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!)
    }
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>取自 <a href="https://stackoverflow.com/questions/7237004/extending-a-line-segment-to-fit-into-a-bounding-box" rel="noreferrer noopener nofollow">this answer</a> , 翻译成 swift 并稍作改动:</p>

<pre><code>func getLines(xmin: CGFloat, ymin: CGFloat, xmax: CGFloat, ymax: CGFloat, x1: CGFloat, x2: CGFloat, y1: CGFloat, y2: CGFloat) -&gt; (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 &lt;= y_for_xmin &amp;&amp; y_for_xmin &lt;= ymax {
      if xmin &lt;= x_for_ymax &amp;&amp; x_for_ymax &lt;= xmax {
            return (CGPoint(x: xmin, y: y_for_xmin), CGPoint(x: x_for_ymax, y: ymax))
      }
      if xmin &lt;= x_for_ymin &amp;&amp; x_for_ymin &lt;= 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 &lt;= y_for_xmax &amp;&amp; y_for_xmax &lt;= ymax {
      if xmin &lt;= x_for_ymin &amp;&amp; x_for_ymin &lt;= xmax {
            return (CGPoint(x: x_for_ymin, y: ymin), CGPoint(x: xmax, y: y_for_xmax))
      }
      if xmin &lt;= x_for_ymax &amp;&amp; x_for_ymax &lt;= 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(&#34; - &#34;, appendNewline: false)
    print(end)

    // Draw main line.
    self.drawLine(line: self.lineLayer!, start: start, end: end)
}
</code></pre>

<p><s>不幸的是,它还没有完全发挥作用,因为在一半的情况下,用于返回正确扩展行的返回 if 构造没有返回任何有用的东西。我会在现在或明天尝试解决这个问题。</s></p><s>

<p>但它应该让你开始</p>

</s><p><s><strong>编辑</strong>:如果起点和终点都在水平轴或垂直轴上,则似乎不起作用。如果它们在不同的轴上,它会起作用。</s></p>

<p><strong>在我添加了三个返回语句后,代码现在可以正常运行了 :)</strong></p>

<p>如果您查看记录的信息,您会发现绘制的线实际上完全延伸到边界,而不是更远。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 为用户创建的给定线路创建线路扩展,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/31775194/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/31775194/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 为用户创建的给定线路创建线路扩展