omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello β€” I'm @olemoritz on Twitter.


    Distance and bearing points in polar plot

    Pythonista
    dist.& bearing law of cosines polar plot
    5
    21
    6450
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • robStacks
      robStacks last edited by ccc

      Hi all,

      I am having a hard time implementing law of cosines in a polar plot.
      Want to get the values of and print distance & beharing from blue to red.

      import matplotlib.pyplot as plt
      import numpy as np
      from math import sqrt, cos
      
      rangeblue = int(input("Range blue ? :"))
      bearingblue = int(input("Bearing blue ? :"))
      rangered = int(input("Range red ? :"))
      bearingred = int(input("Bearing red ? :"))
      
      thetablue= np.deg2rad(bearingblue)
      thetared= np.deg2rad(bearingred)
      
      fig = plt.figure()
      
      ax = fig.add_subplot(111, projection='polar')
      
      ax.scatter(thetablue,rangeblue)
      ax.scatter(thetared,rangered, color='r')
      
      ax.set_theta_direction(-1)
      ax.set_rmax(120)
      ax.set_theta_zero_location('N')
      ax.set_title("Plot", va='bottom')
      
      plt.show()
      

      Thx in advance for any help on this.

      Regards,

      Robert.

      mikael 1 Reply Last reply Reply Quote 0
      • JonB
        JonB last edited by ccc

        Are you having trouble with the above code? Or are you then trying to compute the distances?

        The easiest way to compute distance would be to convert (theta,r) to (x,y) then use standard way to computing distance (or use a vector class that lets you compute length directly)

        See for example
        https://stackoverflow.com/questions/20924085/python-conversion-between-coordinates

        1 Reply Last reply Reply Quote 0
        • robStacks
          robStacks last edited by robStacks

          Hi thx for the tip but i want to use degrees and distance for this one.
          I am trying to implement this formula to get the distance and bearing in degrees from blue point to red point.

          a^2 + b^2 - 2*a*b*cos(c) 
          OR
          c = sqrt(a^2 + b^2 - 2*a*b*cos(c))
          

          But i keep getting errors and or getting bad results with non Sharp angels.

          Any ideas?

          stephen 2 Replies Last reply Reply Quote 0
          • stephen
            stephen @robStacks last edited by

            @robStacks this is what i use for my game development..

            
            def Dist(pos1, pos2):
            	ax, ay = pos1
            	bx, by = pos2
            	dx = pow((bx-ax), 2)
            	dy = pow((by-ay), 2)
            	dist=sqrt(dx+dy)
            	return dist
            	
            def Angle(pos1, pos2):
            	dx, dy = pos1[0]-pos2[0], pos1[1]-pos2[1]
            	angle = degrees(atan2(float(pos1[1]-pos2[1]), float(pos1[0]-pos2[0])))
            	angle += 90 # added 90 deg o that topcenter is zero
            	if angle < 0:
            		angle += 360
            	return angle
            
            
            1 Reply Last reply Reply Quote 0
            • robStacks
              robStacks last edited by

              This post is deleted!
              1 Reply Last reply Reply Quote 0
              • mikael
                mikael @robStacks last edited by

                @robStacks, PyPi is full of vector classes, mine is here. You can use it as shown below, or reference the code for inspiration.

                from vector import Vector
                
                rangeblue = int(input("Range blue:"))
                bearingblue = int(input("Bearing blue:"))
                rangered = int(input("Range red:"))
                bearingred = int(input("Bearing red:"))
                
                blue = Vector(rangeblue, 0)
                blue.degrees = bearingblue
                
                red = Vector(rangered, 0)
                red.degrees = bearingred
                
                delta = red - blue
                
                print('Distance:', delta.magnitude)
                print('Bearing:', delta.degrees)
                
                1 Reply Last reply Reply Quote 2
                • stephen
                  stephen @robStacks last edited by

                  @robStacks ☝🏻☝🏻☝🏻☝🏻☝🏻πŸ’ͺ🏻

                  1 Reply Last reply Reply Quote 1
                  • robStacks
                    robStacks last edited by

                    Works like a charm thx for the help guys!!
                    Just need to round and substract negatieve degrees from 360.
                    But thats easy...πŸ˜ŽπŸ‘πŸ»

                    1 Reply Last reply Reply Quote 0
                    • robStacks
                      robStacks last edited by

                      Sorry for my noobisme but this is my first time coding python.
                      I trying to integrate the above code into sketch.py demo code below.
                      I can't get it to be printed & plotted into (ui.View) so i can draw onto it.

                      '''
                      A very simple drawing 'app' that demonstrates
                      custom views and saving images to the camera roll.
                      '''
                      
                      import ui
                      import photos
                      import console
                      import matplotlib.pyplot as plt
                      import numpy as np
                      from vector import Vector
                      
                      # The PathView class is responsible for tracking
                      # touches and drawing the current stroke.
                      # It is used by SketchView.
                      
                      class PathView (ui.View):
                      	def __init__(self, frame):
                      		self.frame = frame
                      		self.flex = 'WH'
                      		self.path = None
                      		self.action = None
                      	
                      	def touch_began(self, touch):
                      		x, y = touch.location
                      		self.path = ui.Path()
                      		self.path.line_width = 1
                      		self.path.line_join_style = ui.LINE_JOIN_ROUND
                      		self.path.line_cap_style = ui.LINE_CAP_ROUND
                      		self.path.move_to(x, y)
                      	
                      	def touch_moved(self, touch):
                      		x, y = touch.location
                      		self.path.line_to(x, y)
                      		self.set_needs_display()
                      	
                      	def touch_ended(self, touch):
                      		# Send the current path to the SketchView:
                      		if callable(self.action):
                      			self.action(self)
                      		# Clear the view (the path has now been rendered
                      		# into the SketchView's image view):
                      		self.path = None
                      		self.set_needs_display()
                      	
                      	def draw(self):
                      		if self.path:
                      			self.path.stroke()
                      
                      # The main SketchView contains a PathView for the current
                      # line and an ImageView for rendering completed strokes.
                      # It also manages the 'Clear' and 'Save' ButtonItems that
                      # are shown in the title bar.
                      
                      class SketchView (ui.View):
                      	def __init__(self, width=1024, height=1024):
                      		self.bg_color = 'white'
                      		iv = ui.ImageView(frame=(0, 0, width, height))
                      		pv = PathView(frame=self.bounds)
                      		pv.action = self.path_action
                      		self.add_subview(iv)
                      		self.add_subview(pv)
                      		save_button = ui.ButtonItem()
                      		save_button.title = 'Save Image'
                      		save_button.action = self.save_action
                      		clear_button = ui.ButtonItem()
                      		clear_button.title = 'Clear'
                      		clear_button.tint_color = 'red'
                      		clear_button.action = self.clear_action
                      		self.right_button_items = [save_button, clear_button]
                      		self.image_view = iv
                      	
                      	def path_action(self, sender):
                      		path = sender.path
                      		old_img = self.image_view.image
                      		width, height = self.image_view.width, self.image_view.height
                      		with ui.ImageContext(width, height) as ctx:
                      			if old_img:
                      				old_img.draw()
                      			path.stroke()
                      			self.image_view.image = ctx.get_image()
                      	
                      	def clear_action(self, sender):
                      		self.image_view.image = None
                      	
                      	def save_action(self, sender):
                      		if self.image_view.image:
                      			# We draw a new image here, so that it has the current
                      			# orientation (the canvas is quadratic).
                      			with ui.ImageContext(self.width, self.height) as ctx:
                      				self.image_view.image.draw()
                      				img = ctx.get_image()
                      				photos.save_image(img)
                      				console.hud_alert('Saved')
                      		else:
                      			console.hud_alert('No Image', 'error')
                      			
                      #---------------------------------------integrate into sketch.py
                      
                      		bearingblue = int(input("Bearing blue:"))
                      		rangeblue = int(input("Range blue:"))
                      		
                      		bearingred = int(input("Bearing red:"))
                      		rangered = int(input("Range red:"))
                      		
                      		blue = Vector(rangeblue, 0)
                      		blue.degrees = bearingblue
                      		
                      		red = Vector(rangered, 0)
                      		red.degrees = bearingred
                      		
                      		delta = red - blue
                      		
                      		print('Distance:', delta.magnitude)
                      		print('Bearing:', delta.degrees)
                      		
                      		thetablue= np.deg2rad(bearingblue)
                      		thetared= np.deg2rad(bearingred)
                      		
                      		fig = plt.figure()
                      		
                      		ax = fig.add_subplot(111, projection='polar')
                      		
                      		ax.scatter(thetablue,rangeblue)
                      		ax.scatter(thetared,rangered, color='r')
                      		
                      		ax.set_theta_direction(-1)
                      		"""ax.set_rmax(120)"""
                      		ax.set_theta_zero_location('N')
                      		ax.set_title("Plot", va='bottom')
                      		
                      		plt.show()	
                      		
                      #--------------------------------------------		
                      			
                      # We use a square canvas, so that the same image
                      # can be used in portrait and landscape orientation.
                      w, h = ui.get_screen_size()
                      canvas_size = max(w, h)
                      
                      sv = SketchView(canvas_size, canvas_size)
                      sv.name = 'Sketch'
                      sv.present('fullscreen')
                      
                      
                      

                      Do i need to make it a class to be able to do this?

                      Thx in advance for any pointers.

                      Regards,

                      Robert.

                      1 Reply Last reply Reply Quote 0
                      • robStacks
                        robStacks last edited by robStacks

                        I can't seem to find out what the error is about in line 8 & 9
                        Invalid literal for int() with base 10?

                        import matplotlib.pyplot as plt
                        
                        bearing = list()
                        range = list()
                        lines = [line.rstrip('\n') for line in open('waypoints.txt')]
                        for line in lines:
                            stringElement = str.split(line, " ")
                            bearing = int(stringElement[0])
                            range = int(stringElement[1])
                        
                            bearing.append(bearing)
                            range.append(range)
                        
                        ax = plt.subplot(111, projection='polar')
                        
                        #Plot points
                        plt.polar(bearings, ranges)
                        
                        #Plot lines
                        #plt.polar(bearings, ranges)
                        
                        ax.set_theta_direction(-1)
                        ax.set_rmax(120)
                        ax.set_theta_zero_location('N')
                        ax.set_title("Plot", va='bottom')
                        
                        plt.show()
                        

                        What am i doping wrong here?

                        Thx in advance for the help!

                        Regards,

                        Robert.

                        stephen 1 Reply Last reply Reply Quote 0
                        • stephen
                          stephen @robStacks last edited by

                          @robStacks said:

                          I can't seem to find out what the error is about in line 8 & 9
                          Invalid literal for int() with base 10?

                          import matplotlib.pyplot as plt
                          
                          bearing = list()
                          range = list()
                          lines = [line.rstrip('\n') for line in open('waypoints.txt')]
                          for line in lines:
                              stringElement = str.split(line, " ")
                              bearing = int(stringElement[0])
                              range = int(stringElement[1])
                          
                              bearing.append(bearing)
                              range.append(range)
                          
                          ax = plt.subplot(111, projection='polar')
                          
                          #Plot points
                          plt.polar(bearing, range)
                          
                          #Plot lines
                          #plt.polar(angles, values)
                          
                          ax.set_theta_direction(-1)
                          ax.set_rmax(120)
                          ax.set_theta_zero_location('N')
                          ax.set_title("Plot", va='bottom')
                          
                          plt.show()
                          

                          What am i doping wrong here?

                          Thx in advance for the help!

                          Regards,

                          Robert.

                          i really feel like you can only get float from string then you can float to int ind i believe split is called incorrectly try

                          
                          stringElement = line.split(" ")
                               bearing = int(float(stringElement[0]))
                               range = int(float(stringElement[1]))
                          1 Reply Last reply Reply Quote 0
                          • robStacks
                            robStacks last edited by

                            Hmmm closer but Now i get a sintax error strangly onlusten in line 9😩

                            stephen 1 Reply Last reply Reply Quote 0
                            • stephen
                              stephen @robStacks last edited by stephen

                              @robStacks said:

                              Hmmm closer but Now i get a sintax error strangly onlusten in line 9😩

                              here you go buddy 😁

                              i had a min to look at it and there was a few spelling and syntax issues. the way you used str.split felt like C++ or C# is that what you are coming from?

                              in waypoints.txt:

                              50 50
                              100 100
                              150 150
                              

                              Then i ran:

                              
                              import matplotlib.pyplot as plt
                              
                              bearings = list()	# changed bearing β‡’ bearings
                              ranges = list()		# changed range β‡’ ranges
                              lines = [line.rstrip('\n') for line in open('waypoints.txt')]
                              for line in lines:
                              	# changed str.split(line, " ") β‡’ line.split(" ")
                                  stringElement = line.split(" ")	
                                  # Added float parse before int
                                  bearing = int(float(stringElement[0])) 
                                  # Added float parse before int
                                  range = int(float(stringElement[1]))	
                              	
                              	# changed bearing β‡’ bearings
                                  bearings.append(bearing)
                                  # changed range β‡’ ranges
                                  ranges.append(range)		
                              
                              ax = plt.subplot(111, projection='polar')
                              
                              #Plot points
                              plt.polar(bearings, ranges)
                              
                              #Plot lines
                              #plt.polar(bearings, ranges)
                              
                              ax.set_theta_direction(-1)
                              ax.set_rmax(120)
                              ax.set_theta_zero_location('N')
                              ax.set_title("Plot", va='bottom')
                              
                              plt.show()
                              
                              

                              Output:
                              img

                              1 Reply Last reply Reply Quote 1
                              • robStacks
                                robStacks last edited by

                                Hi stephen thx for helping me out with this m8!!!
                                I have very little coding experience python is the deepest ever.
                                But i figured it is most easy to get into and figure out and commonly used.

                                Implemented your corrections but sadly still errors cant convert string to flaot this time in 10
                                I think maybe my pythonista installment is corrupted cause it does run with you

                                import matplotlib.pyplot as plt
                                
                                bearings = list()   # changed bearing β‡’ bearings
                                ranges = list()     # changed range β‡’ ranges
                                lines = [line.rstrip('\n') for line in open('waypoints.txt')]
                                for line in lines:
                                    # changed str.split(line, " ") β‡’ line.split(" ")
                                    stringElement = line.split(" ") 
                                    # Added float parse before int
                                    bearing = int(float(stringElement[0]))
                                    # Added float parse before int
                                    range = int(float(stringElement[1])) 
                                    
                                    # changed bearing β‡’ bearings
                                    bearings.append(bearing)
                                    # changed range β‡’ ranges
                                    ranges.append(range)        
                                
                                ax = plt.subplot(111, projection='polar')
                                
                                #Plot points
                                plt.polar(bearings, ranges, 'k.', zorder=3)
                                
                                #Plot lines
                                #plt.polar(bearings, ranges)
                                
                                ax.set_theta_direction(-1)
                                ax.set_rmax(120)
                                ax.set_theta_zero_location('N')
                                ax.set_title("Plot", va='bottom')
                                
                                plt.show()
                                
                                mikael 1 Reply Last reply Reply Quote 0
                                • mikael
                                  mikael @robStacks last edited by

                                  @robStacks, more likely your input file has some non-printable characters or wrong line breaks.

                                  Try printing out the strings and their len() before trying the conversion to int.

                                  (float is not relevant if you know that you have strings of ints.)

                                  1 Reply Last reply Reply Quote 0
                                  • robStacks
                                    robStacks last edited by

                                    Thx again guys i'm not troubleling any more brain with that monster of a code.
                                    Solved it with numpy
                                    So much easier😎

                                    import matplotlib.pyplot as plt
                                    import numpy  as np
                                    
                                    data = np.loadtxt('waypoints.txt')
                                    
                                    
                                    theta = data[:, 0]
                                    r = data[:, 1]
                                    
                                    ax = plt.subplot(111, projection='polar')
                                    
                                    plt.polar (theta, r)
                                    
                                    ax.set_theta_direction(-1)
                                    ax.set_rmax(120)
                                    ax.set_theta_zero_location('N')
                                    ax.set_title("Plot", va='bottom')
                                    
                                    plt.show()
                                    
                                    stephen 1 Reply Last reply Reply Quote 0
                                    • stephen
                                      stephen @robStacks last edited by

                                      @robStacks your welcome. im glad you found a better way for yourself that means your learning what works for you and that will come in time. two things real fast..

                                      first, when you post code are you using three back ticks and language or just ticks? i noticed your formatting is off.. should be like this

                                      
                                           ```python
                                      
                                      

                                      its not a huge deal but to help yourlelf keep a "coding style" consistant its nessesary to build the discipline πŸ€“


                                      second i know you have moved on but i feel this is a good learning opprotunitynfor yourself and this is because i feel its an easy fix and one that you will need to remember..

                                      inside your waypoints.txt file, like @mikael had asked., what is your output? i feel there might be a , in there since your having a base 10 issue. if you look at mine again you will see my file shows

                                      50 50
                                      100 100
                                      150 150
                                      

                                      feel there is good chance this was the issue 🀠

                                      1 Reply Last reply Reply Quote 0
                                      • robStacks
                                        robStacks last edited by

                                        Yeah it is steep learning for me atm and format is also one of those things i need to learn.
                                        Also i was fiddling around in that code so much to make it work that format got messed.

                                        My textfile is just as your two coloms sep. by one space still use the same now.

                                        18 50
                                        17 60
                                        15 40
                                        12 40
                                        18 50
                                        
                                        1 Reply Last reply Reply Quote 0
                                        • robStacks
                                          robStacks last edited by

                                          Next problemπŸ˜…

                                          Manager to integrate the plot into sketch.py.
                                          But i need to constrain the placing of the plot image.
                                          It jumps to the right halfway out the screen soon as drawing starts

                                          '''
                                          A very simple drawing 'app' that demonstrates
                                          custom views and saving images to the camera roll.
                                          '''
                                          
                                          import ui
                                          import photos
                                          import console
                                          import matplotlib.pyplot as plt
                                          import numpy as np
                                          from io import BytesIO
                                          
                                          # The PathView class is responsible for tracking
                                          # touches and drawing the current stroke.
                                          # It is used by SketchView.
                                          
                                          class PathView (ui.View):
                                          	def __init__(self, frame):
                                          		self.frame = frame
                                          		self.flex = 'WH'
                                          		self.path = None
                                          		self.action = None
                                          	
                                          	def touch_began(self, touch):
                                          		x, y = touch.location
                                          		self.path = ui.Path()
                                          		self.path.line_width = 1
                                          		self.path.line_join_style = ui.LINE_JOIN_ROUND
                                          		self.path.line_cap_style = ui.LINE_CAP_ROUND
                                          		self.path.move_to(x, y)
                                          	
                                          	def touch_moved(self, touch):
                                          		x, y = touch.location
                                          		self.path.line_to(x, y)
                                          		self.set_needs_display()
                                          	
                                          	def touch_ended(self, touch):
                                          		# Send the current path to the SketchView:
                                          		if callable(self.action):
                                          			self.action(self)
                                          		# Clear the view (the path has now been rendered
                                          		# into the SketchView's image view):
                                          		self.path = None
                                          		self.set_needs_display()
                                          	
                                          	def draw(self):
                                          		if self.path:
                                          			self.path.stroke()
                                          
                                          
                                          data = np.loadtxt('waypoints.txt')
                                          
                                          
                                          theta = data[:, 0]
                                          r = data[:, 1]
                                          
                                          ax = plt.subplot(111, projection='polar')
                                          
                                          plt.polar (theta, r)
                                          
                                          ax.set_theta_direction(-1)
                                          ax.set_rmax(120)
                                          ax.set_theta_zero_location('N')
                                          ax.set_title("", va='bottom')
                                          
                                          b = BytesIO()
                                          plt.savefig(b)
                                          bg = ui.Image.from_data(b.getvalue())
                                          
                                          """
                                          
                                          img_view = ui.ImageView(background_color='white')
                                          img_view.content_mode = ui.CONTENT_SCALE_ASPECT_FIT
                                          img_view.image = bg
                                          img_view.present()
                                          
                                          """
                                          
                                          
                                          # The main SketchView contains a PathView for the current
                                          # line and an ImageView for rendering completed strokes.
                                          # It also manages the 'Clear' and 'Save' ButtonItems that
                                          # are shown in the title bar.
                                          
                                          class SketchView (ui.View):
                                          	def __init__(self, width=1024, height=1024):
                                          		self.bg_color = 'white'
                                          		iv = ui.ImageView(frame=(0, 0, width, height))
                                          		iv.image = bg
                                          		iv.content_mode = ui.CONTENT_SCALE_ASPECT_FIT
                                          		pv = PathView(frame=self.bounds)
                                          		pv.action = self.path_action
                                          		self.add_subview(iv)
                                          		self.add_subview(pv)
                                          		save_button = ui.ButtonItem()
                                          		save_button.title = 'Save Image'
                                          		save_button.action = self.save_action
                                          		clear_button = ui.ButtonItem()
                                          		clear_button.title = 'Clear'
                                          		clear_button.tint_color = 'red'
                                          		clear_button.action = self.clear_action
                                          		self.right_button_items = [save_button, clear_button]
                                          		self.image_view = iv
                                          	
                                          	def path_action(self, sender):
                                          		path = sender.path
                                          		old_img = self.image_view.image
                                          		width, height = self.image_view.width, self.image_view.height
                                          		with ui.ImageContext(width, height) as ctx:
                                          			if old_img:
                                          				old_img.draw()
                                          			path.stroke()
                                          			self.image_view.image = ctx.get_image()
                                          	
                                          	def clear_action(self, sender):
                                          		self.image_view.image = None
                                          	
                                          	def save_action(self, sender):
                                          		if self.image_view.image:
                                          			# We draw a new image here, so that it has the current
                                          			# orientation (the canvas is quadratic).
                                          			with ui.ImageContext(self.width, self.height) as ctx:
                                          				self.image_view.image.draw()
                                          				img = ctx.get_image()
                                          				photos.save_image(img)
                                          				console.hud_alert('Saved')
                                          		else:
                                          			console.hud_alert('No Image', 'error')
                                          			
                                          			
                                          # We use a square canvas, so that the same image
                                          # can be used in portrait and landscape orientation.
                                          w, h = ui.get_screen_size()
                                          canvas_size = max(w, h)
                                          
                                          sv = SketchView(canvas_size, canvas_size)
                                          sv.name = 'Sketch'
                                          sv.present('fullscreen')
                                          
                                          
                                          
                                          
                                          1 Reply Last reply Reply Quote 0
                                          • ccc
                                            ccc last edited by

                                            range is a builtin in Python so it would be better to use a different variable name.

                                            robStacks 1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post
                                            Powered by NodeBB Forums | Contributors