# Get perpendicular angle

**URL:** <https://discourse.processing.org/t/get-perpendicular-angle/14067>\
**Category:** Processing.py\
**Created:** [September 19, 2019, 7:38am UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067 "2019-09-19T07:38:13Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![lnp](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/lnp/32/4911_2.png) [@lnp](https://discourse.processing.org/u/lnp)\
**Post date:** [September 19, 2019, 7:38am UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067/1 "2019-09-19T07:38:13Z")

</div>

This is kind of an embarrassing one.

 ![25](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/2/281bcb26040fbf195e39401b0fef0076222af441.png)

I’m trying to draw a perpendicular line to two given vectors and I can’t work it out for the life of me. I suppose what I’m receiving with atan (or PVector.getAngle) is not what I was expecting… ie a degree returned within 360 degrees.

```auto
size(400,400)

nx1, ny1 = 200,100
nx2, ny2 = 100,300

noFill()
strokeWeight(3)
stroke(255,0,0)

line(nx1,ny1, nx2, ny2)

nx3 = nx2-((nx2-nx1)/2)
ny3 = ny2-((ny2-ny1)/2)

ellipse(nx3,ny3,20,20)

stroke(255,255,0)

a = atan2(ny2-ny1, nx2-nx1)

print "angle", a
print "angle deg", degrees(a)

r = 100 # max addition push

a-=90

linex = r * cos(a)
liney = r * sin(a)

line(nx3, ny3, nx3+linex, ny3+liney)

```

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [September 19, 2019, 9:40am UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067/2 "2019-09-19T09:40:24Z")

</div>

try

```auto
#a-=90
a-=PI/2

```

---

<div class="post-metadata">

**Author:** ![tabreturn](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tabreturn/32/3697_2.png) [@tabreturn](https://discourse.processing.org/u/tabreturn)\
**Post date:** [September 19, 2019, 9:56am UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067/3 "2019-09-19T09:56:08Z")

</div>

To add to @kll’s comment –

The [`sin()`](https://py.processing.org/reference/sin.html) and [`cos()`](https://py.processing.org/reference/sin.html) functions work with radians. If you really want to work in degrees, you could convert:

```auto
#a-=90
a-=radians(90)

```

But, it’s probably better to get used to working in radians exclusively.

---

<div class="post-metadata">

**Author:** ![lnp](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/lnp/32/4911_2.png) [@lnp](https://discourse.processing.org/u/lnp)\
**Post date:** [September 19, 2019, 1:32pm UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067/4 "2019-09-19T13:32:37Z")

</div>

lord above…

thanks for that. Egg. on. my. face 🙂

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [September 19, 2019, 2:35pm UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067/5 "2019-09-19T14:35:54Z")

</div>

you like vectors?

```auto
diagp = True # False

def setup():
    size(400, 400)
    smooth()
    noFill()
    strokeWeight(3)
# noLoop()

def draw():
    background(0)
    n1 = PVector(200,100)
# n2 = PVector(100,300)
    n2 = PVector(mouseX,mouseY)
    stroke(255,0,0)
    vline(n1,n2)
    vtext(n1,'1')
    vtext(n2,'2')
    n3 = n2.copy()
    n21= n2.sub(n1) 
    n3 = n3 - n21/2 # midpoint
    vcircle(n3,20)
    vtext(n3,'3')
    a = n21.heading()
    #print 'a', a 
    # ___________________________________________________
    r = 100 
# a-=PI/2 # perpendicular-angle   
# n4 = n3.copy()
# n4 = n4.add( PVector( r*cos(a),r*sin(a) ) )
    n31 = n3.copy().sub(n1)
    n34 = n31.setMag(r).rotate(-PI/2)
    n4 = n3.copy().add(n34)
    # ___________________________________________________
    stroke(255,255,0)
    vline(n3,n4)
    vtext(n4,'4')
    
# let's make our own Vector primitives
def vline(p1, p2):
    line(p1.x, p1.y, p2.x, p2.y)

def vcircle(p,diam):
    circle(p.x,p.y,diam)    

def vtext(p,t):
    if ( diagp ): text(t,p.x,p.y+15)

```

---

<div class="post-metadata">

**Author:** ![villares](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/villares/32/3166_2.png) [@villares](https://discourse.processing.org/u/villares)\
**Post date:** [September 20, 2019, 3:33pm UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067/6 "2019-09-20T15:33:12Z")

</div>

Hey @kll in Python Mode we also have some nice operator overloading for PVectors:

```auto
n21 = n2 - n1
n31 = n3 - n1
n4 = n3 + n34

```

😃

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [September 21, 2019, 3:24am UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067/7 "2019-09-21T03:24:16Z")

</div>

> [@villares](#):
>
> operator overloading for PVectors

works great,  
but compared to

> **[PVector / Reference](https://processing.org/reference/PVector.html)**
>
> A class to describe a two or three dimensional vector, specifically a Euclidean (also known as geometric) vector. A vector is an entity that has both magnitude and direction. The datatype, however, st…

python version

> **[PVector \\ Language (API)](https://py.processing.org/reference/PVector.html)**
>
> Python Mode for Processing extends the Processing Development Environment with the Python programming language.

is very poor AND says

> we cannot simply use traditional addition/multiplication/etc. Instead, we’ll need to do some “vector” math, which is made easy by the methods inside the **PVector** class.

what you prove wrong AND refs to missing methods list.

---

<div class="post-metadata">

**Author:** ![villares](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/villares/32/3166_2.png) [@villares](https://discourse.processing.org/u/villares)\
**Post date:** [September 21, 2019, 6:31pm UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067/8 "2019-09-21T18:31:48Z")

</div>

This makes me so sad. There is an open issue somewhere to fix these docs. It is on my TODO list to work on it, kind of forever ☹

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [September 21, 2019, 8:01pm UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067/9 "2019-09-21T20:01:31Z")

</div>

rewritten for Java

```auto

// https://discourse.processing.org/t/get-perpendicular-angle/14067/5 

boolean diagp = true; // false

void setup() {
  size(400, 400);
  smooth();
  noFill();
  strokeWeight(3);
  // noLoop();
}

void draw() {
  background(0);

  PVector n1 = new PVector(200, 100);
  PVector n2 = new PVector(mouseX, mouseY);

  stroke(255, 0, 0);
  vline(n1, n2);
  vtext(n1, "1");
  vtext(n2, "2");
  PVector n3 = n2.copy();
  PVector n21= n2.sub(n1); 
  n3 = n3.sub(n21.div(2)); // midpoint
  vcircle(n3, 20);
  vtext(n3, "3");

  float a = n21.heading();
  //print 'a', a ;
  // ___________________________________________________
  float r = 100 ;
  // a-=PI/2; // perpendicular-angle   
  // n4 = n3.copy();
  // n4 = n4.add( PVector( r*cos(a),r*sin(a) ) );
  PVector n31 = n3.copy().sub(n1);
  PVector n34 = n31.setMag(r).rotate(-PI/2);
  PVector n4 = n3.copy().add(n34);
  // ___________________________________________________
  stroke(255, 255, 0);
  vline(n3, n4);
  vtext(n4, "4");
}

// ----------------------------------------------------------------

// let's make our own Vector primitives
void vline(PVector p1, PVector p2) {
  line(p1.x, p1.y, p2.x, p2.y);
}

void vcircle(PVector p, float diam) {
  ellipse(p.x, p.y, 
    diam, diam);
}

void vtext(PVector p, String t) {
  if ( diagp )
    text(t, p.x, p.y+15);
}
//

```

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [September 22, 2019, 12:57am UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067/10 "2019-09-22T00:57:17Z")

</div>

thanks @Chrisir,  
yes , there is a interesting question too as i actually translated from JAVA to PYTHON

in JAVA i can do

> java method overloading

```auto
// let's make our own Vector primitives
//void vline(PVector p1, PVector p2) {
void line(PVector p1, PVector p2) {
  line(p1.x, p1.y, p2.x, p2.y);
}

```

but in PYTHON i did not know how to do so i had to invent a ‘vline’ method

> In Python you can define a method in such a way that there are multiple ways to call it.  
> Given a single method or function, we can specify the number of parameters ourself.  
> Depending on the function definition, it can be called with zero, one, two or more parameters.

```auto
# def vline(p1, p2):
def line(p1, p2):
    line(p1.x, p1.y, p2.x, p2.y)

```

> TypeError: line() takes exactly 2 arguments (4 given)

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 22, 2019, 1:20am UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067/11 "2019-09-22T01:20:50Z")

</div>

> [@kll](#):
>
> but in PYTHON i did not know how to do so i had to invent a ‘vline’ method

```auto
def line(p1, p2): this.line(p1.x, p1.y, p2.x, p2.y)
def circle(p, diam): this.circle(p.x, p.y, diam)    
def text(p, t, b=True, offset=15): b and this.text(t, p.x, p.y + offset)

```

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [September 22, 2019, 1:31am UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067/12 "2019-09-22T01:31:58Z")

</div>

kinda works,  
but if i now call

```auto
circle(20,20,20);

```

get the

> #TypeError: circle() takes exactly 2 arguments (3 given)

again, so must use

```auto
this.circle(20,20,20);

```

LOL

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 22, 2019, 2:15am UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067/13 "2019-09-22T02:15:36Z")

</div>

- Python, just like JS and many other languages, functions are stored in variables too.
- It’s not like in Java where we can have a variable/field/parameter, a function/method and a class/interface sharing the same name within the same context:

```auto
void setup() {
  println(same(same) * new same().same); // 60
  exit();
}

char same = 10;

int same(int same) {
  return same / 3;
}

class same {
  short same = 20;
}

```

- For our convenience, most of Processing’s API is made available to us under Python Mode via global variables.
- That is, _size_, _background_, _color_, _triangle_, etc. are all global variables, having a function reference as their value.
- However, when we use `def`, `class` or even the assign `=` operator in the global context, if the label already exists, we end up reassigning its old value w/ a new 1.
- For example, global variable _line_ already exists holding a reference to method PApplet::**line()**.
- When we issue `def line():`, we replace the old Java method w/ a new Python 1.
- But even after that, not all is lost, b/c we still got another global variable named _this_, which holds a reference to current PApplet sketch instance.
- And we can still invoke the original PApplet::**line()** this way: `this.line()`.
- However, once a PApplet member is globally replaced, only via global variable _this_ in order to reach it again.

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 22, 2019, 3:09am UTC](https://discourse.processing.org/t/get-perpendicular-angle/14067/14 "2019-09-22T03:09:10Z")

</div>

> [@kll](#):
>
> again, so must use: `this.circle(20, 20, 20);`

We can still implement the new functions in a way they can deal w/ both PVector and original parameters using the varargs `*` parameter: 🥳

```auto
# def line(p1, p2): this.line(p1.x, p1.y, p2.x, p2.y)
# def circle(p, diam): this.circle(p.x, p.y, diam)    
# def text(p, t, b=True, offset=15): b and this.text(t, p.x, p.y + offset)

def line(p1, p2, *args):
    if args: this.line(p1, p2, *args)
    elif g.is2D(): this.line(p1.x, p1.y, p2.x, p2.y)
    else: this.line(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z)

def circle(p, diam, *args):
    this.circle(p, diam, *args) if args else this.circle(p.x, p.y, diam)

def text(t, p, *args):
    if args: this.text(t, p, *args)
    elif g.is2D(): this.text(t, p.x, p.y)
    else: this.text(t, p.x, p.y, p.z)

```
