1
$\begingroup$

I have this issue and I've been trying to solve this for hours but wasn't able to find a solution which works in all circumstances. I feel sad because this seems like a simple trigonometry problem. I hope you can help me find a solution to this.

What I try to calculate are essentially the red points (I'll call them P later on) at the end of the red lines in this picture: goal The red lines are just for reference and everything is drawn by hand and might therefor not be to scale.

I have a list of coordinates (black points) building a route (black line), for example: [ (12, 9), (13,10), (13,11) ]

In order to find the red points I iterate through the route and look at 3 consecutive points at a time. Where the two edges connect (i.e. the middle point) is a place where the red line starts.

The rules are as follows:

  • given are 3 points: A for after, B for before, C for current (shorthand for each triangle and their meaning in the route)
  • given is j, the length of the red line
  • the angle for BCP and ACP must be the same
  • if multiple answers are possible, choose the one which 'goes with the flow' and is further away from the corner points for it to form a "Y" shape as indicated by the red line
  • calculate the coordinates for each P as (y,x)

To illustrate the issue I made following diagram of just one such iteration: sample (The y-axis on the grid is reversed in this one, but never mind)

What I already managed to do:

  1. Given the points A,B and C, I can calculate the length of the edges as well as the angle ACB=135°. For this I used this function:
def angle_between(previous, current, next):
    a = math.sqrt((next[0]-previous[0])**2 + (next[1]-previous[1])**2)
    b = math.sqrt((current[0]-previous[0])**2 + (current[1]-previous[1])**2)
    c = math.sqrt((current[0]-next[0])**2 + (current[1]-next[1])**2)
    angle_alpha = math.acos((b**2 + c**2 - a**2)/(2*b*c))
    return round(math.degrees(angle_alpha), 2)
  1. I then can calculate PCB=180-(ACB/2)=112.5°.

So I know everything I should need to know except the resulting coordinates of P. I tried to calculate them with the following code but I didn't get the results I expected: P = (C[0] + j*math.cos(PCB_rad) , C[1] + j*math.sin(PCB_rad))

Can someone please help me? Maths is not my strength it seems.. Thx!

$\endgroup$
3
  • 1
    $\begingroup$ This is not a Mathematica question. $\endgroup$
    – yarchik
    Jan 15, 2023 at 8:13
  • $\begingroup$ @yarchik ah I must've mistaken mathematica and math, sorry. Or is there an even better one? $\endgroup$
    – user452354
    Jan 15, 2023 at 9:21
  • $\begingroup$ Welcome to Mathematica SE. To start: 1) take the introductory tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, since the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) consider accepting the answer, if any, that solves your problem, by clicking checkmark sign, 4) give help too, by answering questions in your areas of expertise. $\endgroup$
    – bmf
    Jan 15, 2023 at 15:27

1 Answer 1

8
$\begingroup$

Edit

  • Here we post the explicit formula which can be used to another lanugage.

  • According to the Angle bisector theorem, https://en.wikipedia.org/wiki/Angle_bisector_theorem

  • we can calculate the point d on the ab edge and set dir=c-d as the direction vector from c to p

Clear[a,b,c,d,ca,cb,dir];
a = {xa, ya};
b = {xb, yb};
c = {xc, yc};
ca = Sqrt[(xc - xa)^2 + (yc - ya)^2];
cb = Sqrt[(xc - xb)^2 + (yc - yb)^2];
d =  cb/(ca + cb) *a  + ca/(ca + cb) *b;
dir = c - d;

{xc - (xb *Sqrt[(-xa + xc)^2 + (-ya + yc)^2])/( Sqrt[(-xa + xc)^2 + (-ya + yc)^2] + Sqrt[(-xb + xc)^2 + (-yb + yc)^2]) - ( xa* Sqrt[(-xb + xc)^2 + (-yb + yc)^2])/( Sqrt[(-xa + xc)^2 + (-ya + yc)^2] + Sqrt[(-xb + xc)^2 + (-yb + yc)^2]), yc - (yb *Sqrt[(-xa + xc)^2 + (-ya + yc)^2])/( Sqrt[(-xa + xc)^2 + (-ya + yc)^2] + Sqrt[(-xb + xc)^2 + (-yb + yc)^2]) - ( ya* Sqrt[(-xb + xc)^2 + (-yb + yc)^2])/( Sqrt[(-xa + xc)^2 + (-ya + yc)^2] + Sqrt[(-xb + xc)^2 + (-yb + yc)^2])}

  • Now,p=c+length*Normalize[dir], it can be illustrated as below.
rules = Flatten[
   Thread /@ {{xa, ya} -> {1.2, 2}, {xb, yb} -> {3, 1}, {xc, 
       yc} -> {2.1, 1}}];
rules = Flatten[
   Thread /@ {{xa, ya} -> RandomReal[{-5, 5}, 2], {xb, yb} -> 
      RandomReal[{-5, 5}, 2], {xc, yc} -> RandomReal[{-5, 5}, 2]}];
Graphics[{EdgeForm[Blue], FaceForm[], 
   Triangle[{a, c, b}], {Line[{c, d}]}, 
   Line[{c, c + .5*Normalize[dir]}], Text["a", a, {-1, -1}], 
   Text["b", b, {-1, -1}], Text["c", c, {-.5, 1}], 
   Text["d", d, {-2, -1}], 
   Text["p", c + .5*Normalize[dir], {1, 1}]}] /. rules

enter image description here

Original

Clear[a,b,c,line,dir];
c = {2.1, 1};
a = {1.2, 2};
b = {3, 1};
line = AngleBisector[c -> {a, b}, "Interior"];
dir = line[[2]];
λ = 0.5;
Graphics[{Triangle[{a, b, c}], Red, Line[{c, c - λ*dir}]}]

enter image description here

Clear[λ, bisector, pts];
λ = .5;
bisector[a_, c_, b_] := Module[{line, dir},
   line = AngleBisector[c -> {a, b}, "Interior"];
   dir = line[[2]];
   Line[{c, c - λ*Normalize@dir}]];
pts = {{0, 0}, {3, 2}, {5, 1}, {6, 4}, {10, 3}, {11, 2}, {8, -2}, {7, 
    0}, {4, -2}};
Graphics[{Line[Partition[pts, 2, 1]], Red, 
  bisector @@@ Partition[pts, 3, 1]}]

enter image description here

$\endgroup$
11
  • $\begingroup$ This looks exactly like what I'm looking for! .. But I'm so sorry, I've just been made aware by the comment from @yarchik that I posted this in the wrong forum. You obviously made a great contribution and I don't want to just delete my question and repost it in Math, even though I can't use it in this form. Is there a way I can convert this code into Python code or mathematical formulas for me to copy over? :s $\endgroup$
    – user452354
    Jan 15, 2023 at 9:34
  • 1
    $\begingroup$ @товіаѕ I have post another ideas to calculate the dir from c to p, and also post the formula which only depend on the coordinate of the three points a,c,b. $\endgroup$
    – cvgmt
    Jan 15, 2023 at 11:34
  • 1
    $\begingroup$ @товіаѕ The point of d should be {2.27851, 1.40083} and the dir should be {-0.178513, -0.400826}. $\endgroup$
    – cvgmt
    Jan 15, 2023 at 15:25
  • 1
    $\begingroup$ @товіаѕ as you mentioned in a comment this is the answer you were looking for. Please consider accepting it as well. I will add a proper welcome under the question :-) As always, very impressive answer cvgmt! Kudos $\endgroup$
    – bmf
    Jan 15, 2023 at 15:27
  • 1
    $\begingroup$ @товіаѕ Your Python code should be angle_bisector(a, c, b, length) instead of angle_bisector(a, b, c, length) since we calculate the angle a->c->b $\endgroup$
    – cvgmt
    Jan 15, 2023 at 16:56

You must log in to answer this question.