0
votes

I am currently building an app that controls a robot with joytstick interface; however, I want to plot lidar data; initially, I did this using SpriteKit but I realized the performance was too slow:

How to draw 720 data points using Swift

Now, I am using UIKit

My lidar sensor returns 360 data points i.e. distances; these distances are values of how far it detected an object

I am trying to plot circles on a UIView but the coordinate system is very confusing to me;

here is what I am doing currently: I am translating the distances to cartesian coordinates but this doesn't map nice to UIView's coordinate system since the origin (0,0) is on the top left

How can I translate my coordinate system so that the origin is at "(bounds.width/2, bounds.height/2)"?

As you can see in the picture the dots are displaced

enter image description here

[![import Foundation
import UIKit

@IBDesignable
public class Contours: UIView {

    public var gridColor: UIColor = UIColor.black // { didSet { setNeedsDisplay() }}
    public var gridSize: CGSize = CGSize(width: 100, height: 100) // { didSet { setNeedsDisplay() }}
    public var gridView = UIView(frame: CGRect(origin: .zero, size: .zero))

    public var dataSize: CGSize = CGSize(width: 10, height: 10) // { didSet { setNeedsDisplay() }}
    public var dataColor: UIColor = UIColor.blue // { didSet { setNeedsDisplay() }}
    public var dataView = UIView(frame: CGRect(origin: .zero, size: .zero))

    public var fade: CGFloat = 0.5 { didSet { setNeedsDisplay() }}

    public var distances: \[Int\] = \[2601, 2600, 33, 2608, 2601, 2594, 2625, 2633, 2637, 2651, 2656, 2666, 2683, 2690, 2705, 2712, 2712, 2739, 2752, 53, 1103, 1060, 1019, 980, 944, 911, 33, 851, 826, 801, 777, 757, 737, 718, 701, 683, 667, 654, 53, 486, 470, 457, 448, 440, 432, 424, 416, 409, 403, 396, 389, 383, 378, 372, 367, 362, 357, 353, 348, 344, 340, 336, 333, 329, 326, 323, 319, 317, 314, 311, 309, 307, 305, 303, 301, 299, 298, 297, 295, 294, 293, 292, 291, 290, 290, 290, 290, 291, 293, 295, 303, 386, 383, 53, 350, 53, 53, 53, 53, 53, 3, 364, 362, 360, 356, 358, 355, 353, 351, 350, 349, 347, 345, 53, 53, 53, 308, 3, 309, 309, 312, 313, 315, 316, 319, 321, 53, 329, 332, 335, 332, 53, 53, 53, 53, 53, 53, 53, 3, 53, 53, 53, 53, 53, 53, 670, 33, 706, 728, 750, 772, 799, 825, 856, 887, 925, 755, 749, 744, 739, 734, 730, 727, 722, 719, 716, 714, 634, 709, 706, 704, 703, 701, 699, 700, 695, 697, 697, 338, 696, 697, 696, 698, 698, 700, 702, 703, 705, 707, 710, 712, 714, 718, 53, 53, 53, 53, 53, 53, 53, 53, 3, 53, 53, 53, 53, 53, 53, 53, 53, 3, 53, 53, 53, 53, 53, 53, 53, 3412, 3397, 3384, 53, 3538, 3603, 53, 2426, 2412, 2363, 2330, 2288, 2262, 2214, 2190, 2162, 2130, 53, 53, 53, 2807, 2631, 2408, 2638, 2607, 2601, 2562, 2534, 2515, 2496, 2478, 2462, 2445, 53, 53, 53, 1751, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 3, 53, 53, 53, 53, 53, 2643, 2643, 53, 2660, 53, 2528, 2523, 2221, 1955, 1684, 1677, 1684, 1694, 1705, 1202, 1204, 1211, 1217, 1225, 1233, 1239, 1249, 1259, 1270, 1280, 1289, 1280, 1011, 991, 977, 968, 966, 964, 968, 975, 984, 1003, 2, 53, 1297, 53, 53, 33, 1321, 1299, 1274, 1254, 1233, 1232, 1264, 1293, 3802, 53, 53, 53, 53, 53, 53, 53, 3, 53, 2878, 2870, 2848, 2821, 2803, 2788, 2769, 2753, 2740, 2708, 2711, 2701, 2682, 2656, 2664, 2644, 2644, 2631, 2626, 2616, 2610, 2604, 2605, 2605, 2600, 2598, 2603\]

//    public var circleViews: \[UIView\] = \[\]
    public var distx: \[Double\] = \[\]
    public var disty: \[Double\] = \[\]
    public var scalex: \[Double\] = \[\]
    public var scaley: \[Double\] = \[\]

    override public init(frame: CGRect) {
        super.init(frame: frame)
    }

    public required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    public override func draw(_ rect: CGRect) {

        alpha = 1
        layer.backgroundColor = gridColor.cgColor

        for index in 0...356 {
            let radians = Double(index) * M_PI / 180.0
            let x = Double(distances\[index\]) * cos(Double(radians))
            let y = Double(distances\[index\]) * sin(Double(radians))
            distx.append(x)
            disty.append(y)
        }

        let xmin: Double = Double(distx.min()!)
        let xmax: Double = Double(distx.max()!)
        let ymin: Double = Double(disty.min()!)
        let ymax: Double = Double(disty.max()!)

        let scale = max(xmax - xmin, ymax - ymin)

        var circles = \[UIView\]()
        circles.reserveCapacity(360)
        for _ in 0...356 {
            circles.append(UIView(frame: CGRect(origin: .zero, size: .zero)))
        }

//        CGSize(width: 30, height: 30)
//        circles\[index\].alpha = 1
//        circles\[index\].frame = CGRect(origin: CGPoint(x: bounds.width/2, y: bounds.height/2), size: dataSize)
//        circles\[index\].center = CGPoint(x: x, y: y)
//        circles\[index\].layer.backgroundColor = dataColor.cgColor
//        circles\[index\].layer.cornerRadius = circles\[index\].bounds.width / 2

        print("width: \(bounds.width), height: \(bounds.height)")

        for index in 0...356 {
            let radians = Double(index) * M_PI / 180.0
            let x = ((Double(distances\[index\]) * cos(Double(radians)) / scale) * Double(bounds.width))
            let y = (Double(distances\[index\]) * sin(Double(radians)) / scale) * Double(bounds.height)

            circles\[index\].alpha = 1
            circles\[index\].frame = CGRect(origin: .zero, size: dataSize)

//            circles\[index\].frame = CGRect(origin: CGPoint(x: bounds.width/2, y: bounds.height/2), size: dataSize)
            circles\[index\].center = CGPoint(x: x, y: y)
            circles\[index\].layer.backgroundColor = dataColor.cgColor
            circles\[index\].layer.cornerRadius = circles\[index\].bounds.width / 2

            print("x: \(x), y: \(y)")
//            print("zero: \(layer.anchorPoint)")

            if let superview = circles\[index\].superview {
                superview.bringSubview(toFront: circles\[index\])
            } else {
                addSubview(circles\[index\])
            }

//            scalex.append(x)
//            scaley.append(y)
        }

    }

    private func reset() {
        UIView.animate(withDuration: 0.25) { () -> Void in
            self.gridView.center = CGPoint(x: self.bounds.width / 2, y: self.bounds.height / 2)
        }
    }

}][1]][1]
1

1 Answers

0
votes

Your code is currently using addSubview within the Contours class. Therefore the circles will be relative to the bounds of the contours view. I assume the contours view has an origin at the top left of the screen, whereas you need to set its frame to be like that for however you're drawing the red rectangle.