SH_IQ
SH_IQ

Reputation: 709

How could I apply the idea of clockwise and counterclockwise in Python?

I'm new to the Python program and I have this picture below that has two angles (-18, 27). The signs of these angles have been assigned according to the idea of clockwise and counterclockwise. How could such an idea can be translated in Python?

I mean the idea of clockwise and counterclockwise. Any examples that show this idea.

How could I put conditions in python that say clockwise and counterclockwise?

clockwise and counterclockwise

**This description below for the above picture:**

We now discuss the key concept of an angle range. AP Theta* maintains two additional values for every vertex s, namely a lower angle bound lb(s) of vertex s and an upper angle bound ub(s) of vertex s, that together form the angle range [lb(s), ub(s)] of vertex s. The angle bounds correspond to headings of rays (measured in degrees) that originate at the parent of vertex s. The heading of the ray from the parent of vertex s to vertex s is zero degrees. A visible neighbor of vertex s is guaranteed to have line-of-sight to the parent of vertex s if (but not necessarily only if) the heading of the ray from the parent of vertex s to the visible neighbor of vertex s is contained in the angle range of vertex s. Figure 4.14 shows an example where vertex C3 with parent A4 has angle range [−18, 27]. Thus, all visible neighbors of vertex C3 in the red region are guaranteed to have line-of-sight to the parent of vertex C3. For example, vertex C4 is guaranteed to have line-of-sight to the parent of vertex C3 but vertex B2 is not. AP Theta* therefore assumes that vertex B2 does not have line-of-sight to the parent of vertex C3.

We now define the concept of an angle range more formally. angle(s, p, s′) ∈ [−90, 90], which gives AP Theta* its name, is the angle (measured in degrees) between the ray from vertex p to vertex s and the ray from vertex p to vertex s′. It is positive if the ray from vertex p to vertex s is clockwise from the ray from vertex p to vertex s′, zero if the ray from vertex p to vertex s has the same heading as the ray from vertex p to vertex s′, and negative if the ray from vertex p to vertex s is counterclockwise from the ray from vertex p to vertex s′. Figure 4.14 shows an example where angle(C3,A4,C4) = 27 degrees and angle(C3,A4,B3) = −18 degrees. A visible neighbor s′ of vertex s is guaranteed to have line-of-sight to the parent of vertex s if (but not necessarily only if) angle(s, parent(s), s′) ∈ [lb(s), ub(s)] (Visibility Property).

Upvotes: 1

Views: 1210

Answers (3)

user7711283
user7711283

Reputation:

The previous answers address the issue in detail of the specific case and are missing to provide the most obvious pythonic concept of clockwise and counterclockwise actually asked for in the question.

In order to implement in Python the concept of clockwise and counterclockwise, Python provides along with atan in its build-in math module also the atan2 method.

The math.atan2 method allows to implement the concept of clockwise and counterclockwise by assigning an angle value to each possible vector (including [0,0] assuming it to be [0,1].

To illustrate how it works in practice let's assume the vector V0 = (Vx0, Vy0) as the reference vector and V1 = (Vx1, Vy1) , V2 = (Vx2, Vy2) as vectors for clockwise and counterclockwise aware calculation of angle between them and the reference vector V0:

example

from math import atan2, pi

A4 = [4,-1]
C4 = [4,-3]; V1 = [4-4, -3-(-1)]
C3 = [3,-3]; V0 = [3-4, -3-(-1)]
C2 = [2,-3]; V2 = [2-4, -3-(-1)]

def Vangle_0to360deg(x,y):
    # positive number starting with 0 zero for Vxy with x,y=-1,0
    # with values increasing counterclockwise (0 <= Vangle < 360)
    return (180+180*atan2(y,x)/pi)%360

a = Vangle_0to360deg

print(f'{a(*V1):3.0f}')
print(f'{a(*V0):3.0f}')
print(f'{a(*V2):3.0f}')
print('---')
print(f'{a(*V1)-a(*V0):3.0f}')
print(f'{a(*V2)-a(*V0):3.0f}')

printing

 90
 63
 45
---
 27
-18

what is exactly the required functionality.

The order of the arguments in the vector angle subtraction decides about the positive or negative result. Setting the reference arm of the angle to the value which will be subtracted, positive values of angle mean counterclockwise.

Upvotes: 0

GPrathap
GPrathap

Reputation: 7820

I guess this is what you are looking for

import numpy as np

def unit_vector(vector):
    """ Returns the unit vector of the vector.  """
    return vector / np.linalg.norm(vector)

def angle_between(v1, v2):
    """ Returns the angle in radians between vectors 'v1' and 'v2'::
    """
    v1_u = unit_vector(v1)
    v2_u = unit_vector(v2)
    return np.rad2deg(np.arccos(np.clip(np.dot(v1_u, v2_u), -1.0, 1.0)))

a4 = np.array([0,3])
c3 = np.array([2,2])
b3 = np.array([1,2])
c4 = np.array([2,3])

c4_a4 = c4 - a4
c3_a4 = c3 - a4
b3_a4 = b3 - a4


angle_b3_c3 = angle_between(c3_a4, b3_a4)
angle_c3_c4 = angle_between(c3_a4, c4_a4)

print angle_b3_c3  
print angle_c3_c4

Output:

18.4349488229
26.5650511771

Note: here I am assuming each box has unit width and height analogy with a grid as shown below, enter image description here. Thus, for example a1 = {0,0}, a2 = {0,1}, a3={0,2}, a4={0,3}, a5={0,4}, b1 = {1,0}, b2 = {1,1}, b3={1,2} and so on; In here, rows corresponded to a, b, c, d and and columns correspond to indexing of rows (e.g., a1, a2, etc)

Based on the direction you have to multiply by -1 to get clockwise or anti-clockwise

Upvotes: 2

bad_coder
bad_coder

Reputation: 12900

I would recommend implementing an Enum to define this. Seems like the perfect and most pythonic choice to go for. Simple example:

from enum import Enum


class ClockMotion(Enum):

    Clockwise = 1
    CounterClockwise = -1

    @classmethod
    def check_motion(cls, angle1, angle2):
        if angle2 - angle1 > 0:
            return cls.Clockwise
        else:
            return cls.CounterClockwise

Testing:

>>>ClockMotion.check_motion(-30, 60)
ClockMotion.Clockwise

For the Vertex use a simple class since it'll have instance values:

class Vertex:

    def __init__(self, lb, ub):
        self.lb = lb
        self.ub = ub

Upvotes: 0

Related Questions