Repository: sympy/sympy
Pull request: line - added fix to define horizontal and vertical lines using Eq instead of Point
<!-- Your title above should be a short description of what
was changed. Do not include the issue number in the title. -->

#### References to other Issues or PRs
<!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
format, e.g. "Fixes #1234" (see
https://tinyurl.com/auto-closing for more information). Also, please
write a comment on that issue linking back to this pull request once it is
open. -->


#### Brief description of what is fixed or changed
Fixes #22361 and now we can define horizontal and vertical lines using `Eq`. `Line(Eq(x, 1))` now returns `Line2D(Point2D(1, 0), Point2D(1, 1))` instead of `ValueError: could not find y` .

#### Other comments


#### Release Notes

<!-- Write the release notes for this release below between the BEGIN and END
statements. The basic format is a bulleted list with the name of the subpackage
and the release note for this PR. For example:

* solvers
  * Added a new solver for logarithmic equations.

* functions
  * Fixed a bug with log of integers.

or if no release note(s) should be included use:

NO ENTRY

See https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more
information on how to write release notes. The bot will check your release
notes automatically to see if they are formatted correctly. -->

<!-- BEGIN RELEASE NOTES -->
* geometry
   * `Line` class can now define horizontal and vertical lines using `Eq`
<!-- END RELEASE NOTES -->


Problem statement:
Line with equation doesn't support horizontal or vertical lines
```
from sympy import Point, Eq, symbols
from sympy.geometry import Line, Segment
from sympy.abc import x, y

a, b, c, e, f, g, h = symbols('a, b, c, e, f, g, h')
AC = Line(Eq(y, a*x + c))
DF = Line(Eq(y, f))
```

SymPy throws `ValueError: could not find x` in the last line.

Are there only ways to represent such horizontal or vertical lines with two points, or one point with a slope oo or 0?

Hints from issue discussion:
Sympy throws `ValueError: could not find x` for `Line(Eq(y, f))`.
This error can be avoided by defining `x` as `f` .
```
>>> Line(Eq(y, f), x = f)
Line2D(Point2D(0, 0), Point2D(1, 1))
```
Yes. SymPy tries to "do the right thing" but sometimes you have to provide more input. The docstring, too, is helpful in resolving these issues:
```
The line corresponding to an equation in the for `ax + by + c = 0`,
can be entered:

>>> Line(3*x + y + 18)
Line2D(Point2D(0, -18), Point2D(1, -21))

If `x` or `y` has a different name, then they can be specified, too,
as a string (to match the name) or symbol:

>>> Line(Eq(3*a + b, -18), x='a', y=b)
```
Hi @praneethratna and @smichr , both your cases are neither horizontal nor vertical.

I mean, could you provide examples to define such lines just by providing `Eq` instead of `Point`?

For example: `Eq(x, 1)` is a vertical line passing through `Point(1, 0)`, `Eq(y, 1)` is a horizon passing through `Point(0, 1)`. Can you define such lines without inputing `Point(1, 0)` or `Point(0, 1)`?
Sorry for my error paste. The error for the last line is `ValueError: could not find x` but not `ValueError: could not find y`.

Commit message: fixed error

Patch to review:
diff --git a/sympy/geometry/tests/test_line.py b/sympy/geometry/tests/test_line.py
index 89af9cfc844d..7733c056a820 100644
--- a/sympy/geometry/tests/test_line.py
+++ b/sympy/geometry/tests/test_line.py
@@ -802,3 +802,8 @@ def test_issue_8615():
     a = Line3D(Point3D(6, 5, 0), Point3D(6, -6, 0))
     b = Line3D(Point3D(6, -1, 19/10), Point3D(6, -1, 0))
     assert a.intersection(b) == [Point3D(6, -1, 0)]
+
+
+def test_issue_22361():
+    assert Line(Eq(x, 1)) == Line2D(Point2D(1, 0), Point2D(1, 1))
+    assert Line(Eq(y, 1)) == Line2D(Point2D(0, 1), Point2D(1, 1))
diff --git a/sympy/geometry/util.py b/sympy/geometry/util.py
index fb85ecc433e9..4c98f190b0b0 100644
--- a/sympy/geometry/util.py
+++ b/sympy/geometry/util.py
@@ -27,7 +27,9 @@ def find(x, equation):
 
     free = equation.free_symbols
     xs = [i for i in free if (i.name if isinstance(x, str) else i) == x]
-    if not xs:
+    if not xs and (str(equation) != x):
+        return 1
+    if str(equation) == x:
         raise ValueError('could not find %s' % x)
     if len(xs) != 1:
         raise ValueError('ambiguous %s' % x)


Code review comments:
diff_hunk: @@ -27,7 +27,9 @@ def find(x, equation):
 
     free = equation.free_symbols
     xs = [i for i in free if (i.name if isinstance(x, str) else i) == x]
-    if not xs:
+    if not xs and (str(equation) != x):
path: sympy/geometry/util.py
text: @user1:
I recommend against changing `find` in this way. One might have the equation `2*y + 1` which is another way of saying `y = 1/2`.