How to choose three points on the circle so that the triangle is not a right triangle?

I want to choose three points $A$, $B$, $C$ has integer coordinates on the circle $$(x+2)^2 + (y+1)^2 = 25$$ so that the triangle is not a right triangle. But I can not. I tried

ClearAll[a, b, r];
a = -2;
b = -1;
r = 5;
Solve[{(x - a)^2 + (y - b)^2 == r^2, x != a, y != b}, {x, y}, Integers]

-
Choose them so no two are the end points of a diameter. – Michael E2 Jun 23 '13 at 14:25

With the solutions you already found, you can generate all possible triangles:

ss = Subsets[{x, y} /.
Solve[{(x - a)^2 + (y - b)^2 == r^2, x != a, y != b}, {x, y}, Integers],
{3}
]


Now, select from those the ones not containing an angle of 90 degrees (with integers, Mathematica is smart enough to find exact right angles where they occur, so we can test for $\frac{\pi}{2}$):

res =
Pick[ss,
(FreeQ[#, π/2] &) /@
({VectorAngle[#2 - #1, #3 - #1],
VectorAngle[#1 - #2, #3 - #2],
VectorAngle[#1 - #3, #2 - #3]
} & @@@ ss)
];


Display the 32 results:

Partition[
Graphics[{Circle[{-2, -1}, 5], Polygon[#], Red, Point /@ ss},
ImageSize -> {{80}, {80}}
] & /@ res,
8
] // Grid


The remaining 24 have a right angle, just put a Not in front of the FreeQ above to find them. Displaying that:

-
Maybe include Circle[{-2, -1}, 5] too, to facilitate visualization. – J. M. Jun 23 '13 at 15:49
@0x4A4D I was too lazy, but I bit the bullet. Done. – Sjoerd C. de Vries Jun 23 '13 at 15:57
How to list the coordinates of all this triangle (not a right triangle)? – minthao_2011 Jun 24 '13 at 0:31
Ok. res = Pick[ ss, (FreeQ[#, [Pi]/2] &) /@ ({VectorAngle[#2 - #1, #3 - #1], VectorAngle[#1 - #2, #3 - #2], VectorAngle[#1 - #3, #2 - #3]} & @@@ ss)] – minthao_2011 Jun 24 '13 at 2:18
@minthao_2011 The 2nd of my 3 lines of code, indeed. that wasn't so difficult, was it? – Sjoerd C. de Vries Jun 24 '13 at 5:30

Here's a way to implement the solution in a single Solve, all 960 of them. The determinant is zero if the three points you get by dropping the 1's are colinear; if they are, they lie on a diagonal, and either the solution is a right triangle or two points are coincident (i.e. no triangle). Dividing by the determinant rules out these cases.

circleRules = {r -> 5, a -> -2, b -> -1};
sols = Solve[{
((p - a)^2 + (q - b)^2 - r^2) /
Det[ {{a, b, 1},
{u, v, 1},
{s, t, 1}} ] == 0,
((s - a)^2 + (t - b)^2 - r^2) /
Det[ {{a, b, 1},
{p, q, 1},
{u, v, 1}} ] == 0,
((u - a)^2 + (v - b)^2 - r^2) /
Det[ {{a, b, 1},
{p, q, 1},
{s, t, 1}} ] == 0} /. circleRules,
{p, q, s, t, u, v}, Integers];


Here's a faster way to do the same thing:

sols2 = Solve[{(p - a)^2 + (q - b)^2 - r^2 == 0,
(s - a)^2 + (t - b)^2 - r^2 == 0,
(u - a)^2 + (v - b)^2 - r^2 == 0} /. circleRules,
{p, q, s, t, u, v}, Integers];
figs = {{p, q}, {s, t}, {u, v}} /. # & /@ sols2;
nonRtTri2 =
Pick[figs,
Unitize[Times @@ Flatten @
Minors[Transpose[#~Append~{a, b} /. circleRules]~Append~{1, 1, 1, 1},
3] & /@ figs],
1];


Consistency:

nonRtTri = {{p, q}, {s, t}, {u, v}} /. # & /@ sols;
nonRtTri == nonRtTri2
(* True *)


What they look like:

allPts = Union @ Flatten[{{p, q}, {s, t}, {u, v}} /. # & /@ sols, 1];
Graphics[{Circle[{a, b}, r] /. {r -> 5, a -> -2, b -> -1},
Polygon[{{p, q}, {s, t}, {u, v}}] /. #, Red, Point[allPts]},
ImageSize -> 80] & /@ sols;


-
In his code, the OP seems to explicitely exclude the coordinates on the x and y axis. It is not clear to me whether or not this is part of the actual question. – Sjoerd C. de Vries Jun 24 '13 at 13:17
@SjoerdC.deVries Thanks. I was careless with that detail and just read the text. I guess, thinking about it, I'm not sure whether the text or the code should be taken as definitive. – Michael E2 Jun 24 '13 at 13:44

First lets find the integer coordinates on your circle.

ClearAll[a, b, r];
a = -2;
b = -1;
r = 5;
points = {x, y} /.Solve[{(x - a)^2 + (y - b)^2 == r^2}, {x, y}, Integers];


Now you want to choose those points which doesn't form a right triangle. Since I don't know if you need a list of all possible points or any point, I will do a RandomChoice. You can put the whole thing in a loop to generate a set.

p1 = {x1, y1} = RandomChoice[points];
p2 = {x2, y2} = RandomChoice[Cases[points, Except[p1]]];
p3 = {x3, y3} = RandomChoice[Cases[points, Except[{p1, p2}]]];
R12 = (y2 - y1)^2 + (x2 - x1)^2;
R23 = (y3 - y2)^2 + (x3 - x2)^2;
R31 = (y1 - y3)^2 + (x1 - x3)^2;
If[R12 + R23 != R31 && R23 + R31 != R12 && R31 + R12 != R23,
set = {p1, p2, p3},set=Null]


You can check the angles as well and the position of the triangle also

\[Theta]12 = ArcCos[(R23 + R31 - R12)/(2. Sqrt[R23 *R31])]*180/\[Pi];
\[Theta]23 = ArcCos[(R31 + R12 - R23)/(2. Sqrt[R31*R12])]*180/\[Pi];
\[Theta]31 = ArcCos[(R12 + R23 - R31)/(2. Sqrt[R12*R23])]*180/\[Pi];
Show[{ContourPlot[(x - a)^2 + (y - b)^2 == r^2, {x, a - r, a + r}, {y,b - r, b + r}, PlotLabel -> {\[Theta]12, \[Theta]23, \[Theta]31}],Graphics[Polygon[set]]}]


If there is a Null output one of the angles will be 90. and you have to execute the loop again. Or you can use a loop.

Alternatively you can use the the angles (If[theta(i,j)!=90.&&...,set={p1,p2,p3}]) to filter out your desired set and then you can choose triangle with any angle.

-

Edit

I have modified my code to honor the constraint that the chosen points must have integer coordinates.

I decided to see if,using only simple geometric notions, I could write a function generating a random triangle meeting the stated criterion each time it was called. Here is what I came up with:

First two auxiliary functions.

intPts[xy_, r_, n_] :=
Module[{x, y},
RandomSample[{x, y} /.
Solve[(x - xy[[1]])^2 + (y - xy[[2]])^2 == r^2, Integers],
n]]

notDiameterQ[{u_, v_}, r_, δ_] := EuclideanDistance[u, v] < (2 - δ) r


The first auxiliary function returns n points having Integer coordinates that lie on the circumference of a circle with center xy and radius r and such that they have integer coordinates.. The second tests for a line segment being less than a diameter of circle of radius r. It returns True if the distance between points u and v is less than a 2 r by the amount δ and returns False otherwise.

The main function, triangle, returns three randomly selected points on a circle with center xy and having radius r and satisfying the constraints of having integer coordinates and not forming a right triangle.

triangle[xy_, r_] :=
Module[{pts, pairs},
pts = intPts[xy, r, 3];
(* to test all three sides of the triangle, all three pairing of points are needed  *)
pairs = Subsets[pts, {2}];
(* if the points are OK, return them, otherwise try again *)
If[And @@ (notDiameterQ[#, r, .05]& /@ pairs), pts, triangle[xy, r]]]

SeedRandom[4]; pts = triangle[{-2, -1}, 5];
Graphics[{Circle[{-2, -1}, 5], PointSize[Large], Point[{-2, -1}], Red,
Point[pts]}, Frame -> True, Axes -> True]


-
What about the integer coordinates requirement? – Sjoerd C. de Vries Jun 24 '13 at 5:24
@SjoerdC.deVries Oops, missed that somehow. I'll look into fixing my answer. – m_goldberg Jun 24 '13 at 11:23

Just for fun, this is much faster than Solve..

Last@Last@
Reap[Do[ If[(x - a)^2 + (y - b)^2 == r^2 && x != a && y != b,
Sow[{x, y} ]], {y, -r + b, r + b}, {x, -r + a, r + a}]]


For a one line solution..

Graphics[{Circle[{a, b}, r], Polygon[#]}] & /@
Select[ Subsets[ ( (
Last@Last@Reap[
Do[ If[(x - a)^2 + (y - b)^2 == r^2 && x != a && y != b, Sow[{x, y} ]],
{y, -r + b, r + b}, {x, -r + a, r + a}]])), {3}] ,
And @@ ( Function[ pts, Mean[pts] != {a, b}] /@
Subsets[#, {2}] ) & ]

-
Nice, but I think it should be pointed out that as r grows Solve eventually wins the speed contest. – Michael E2 Jun 24 '13 at 22:32