Skip to content

Commit

Permalink
[23_27] Fix bugs when drawing semicircle
Browse files Browse the repository at this point in the history
<!-- Thank you for your contribution! -->
## What
Fix 2 little bugs.
1. Can not draw the correct semicircle in current environment.
2. There will be "division by zero" exception in console when you're
choosing the third point and move mouse to center point (the first
point).
## Why
When drawing an arc, we first select the circle center `c`, then the
start point `p` and end point `x` on the arc.
It will use these points to calculate a third point `m` on arc, and use
`p`, `m`, `x` to draw the arc.
By default it's counterclockwise though it's called "Std-arc".
When we want to draw a semicircle, the angle between `vec-c-p` and
`vec-c-q` is 180.
In the previous code, it uses `vec-c-p` as the third point `m`
incorrectly.
We should still consider it's clockwise or counterclockwise here and
then add the correct vector to the center point as the third point.
Before:
<img width="359" alt="image"
src="https://github.com/user-attachments/assets/af809f31-24bc-4a44-a4cf-2beae33fd9b4"
/>

Fixed:
<img width="361" alt="image"
src="https://github.com/user-attachments/assets/18d8c93a-d491-4d8d-843c-59d31298bd3d"
/>

The distance of `c` and `q` as `r1` is used to avoid the exception
message in console, like
```
;/: division by zero, (/ 0.0 0.0)
;    (let ((n (length opts))) (cond ((= n...
;    D:\mogan\build\packages\app.mogan\data\progs\kernel\library\base.scm, line 270, position: 0
; (let ((n (length opts))) (cond ((= n 0) (... ; f: 0.0
; (f2s (/ (point-get-x pt) f))               ; pt: (point "0.0" "0.0")
; (list-values 'point (f2s (/ (point-get-x ...
; std-arc-helper: (equal? (point-get-unit v... ; vec-c-p: (point "2.0" "0.0")
;                                              vec-c-q: (point "0.0" "0.0")
```
## How to test your changes?
Add a unit test so I can test it by `xmake run 23_27`
  • Loading branch information
wind1900 authored Jan 12, 2025
1 parent f50c989 commit 21da23f
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 7 deletions.
18 changes: 11 additions & 7 deletions TeXmacs/progs/graphics/graphics-markup.scm
Original file line number Diff line number Diff line change
Expand Up @@ -87,28 +87,32 @@
(p (if (tm-point? P) (tree->stree P) c))
(q (if (tm-point? Q) (tree->stree Q) p))
(r (points-distance c p))
(x (if (equal? r 0.0)
(r1 (points-distance c q))
(x (if (zero? r)
c
(points-add (point-times (point-get-unit (points-sub q c)) r) c)))
(if (zero? r1)
p
(points-add (point-times (point-get-unit (points-sub q c)) r) c))))
(mid-p-x (points-mid p x))
(vec-c-p (points-sub p c))
(vec-c-q (points-sub q c))
(m (if (equal? r 0.0)
c
(m (if (or (zero? r) (zero? r1))
x
(if (clockwise (points-cross-product-k vec-c-p vec-c-q) 0)
(points-add (point-times (point-get-unit (points-sub mid-p-x c)) (- r)) c)
(if (= (points-cross-product-k vec-c-p vec-c-q) 0)
;; If cross product == 0, then the angle between vec-c-p and vec-c-q is 0 or 180.
;; We should find out whether it's 0 or 180.
;; And we should determine whether it's clockwise or counterclockwise.
(if (equal? (point-get-unit vec-c-p) (point-get-unit vec-c-q))
x
(point-rotate-90 (point-rotate-90 (point-rotate-90 vec-c-p))))
(if (eq? clockwise >)
(points-add (point-rotate-90 (point-rotate-90 (point-rotate-90 vec-c-p))) c)
(points-add (point-rotate-90 vec-c-p) c)))
(points-add (point-times (point-get-unit (points-sub mid-p-x c)) r) c))))))
`(arc ,p ,m ,x)))




(define-graphics (std-arc C P Q)
(std-arc-helper C P Q >))

Expand Down
78 changes: 78 additions & 0 deletions TeXmacs/tests/23_27.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
(import (liii check)
(liii os))

; Because std-arc-helper is using define, it is not using tm-define
; We have to load the module directly
;
; (texmacs-module (tests 23_27)
; (:use (graphics graphics-markup)))
(load (string-append (getenv "TEXMACS_PATH") "/progs/graphics/graphics-markup.scm"))

(define (point x y)
(stree->tree `(point ,x ,y)))

(define (test-std-arc-helper)
;c==p==q
(check (std-arc-helper (point "0" "0") (point "0" "0") (point "0" "0") #f)
=> `(arc (point "0" "0")
(point "0" "0")
(point "0" "0")))
;c==p
(check (std-arc-helper (point "0" "0") (point "0" "0") (point "1" "1") #f)
=> `(arc (point "0" "0")
(point "0" "0")
(point "0" "0")))
;c==q
(check (std-arc-helper (point "0" "0") (point "1" "1") (point "0" "0") #f)
=> `(arc (point "1" "1")
(point "1" "1")
(point "1" "1")))
;p==q
(check (std-arc-helper (point "0" "0") (point "1" "0") (point "1" "0") >)
=> `(arc (point "1" "0")
(point "1.0" "0.0")
(point "1.0" "0.0")))
(check (std-arc-helper (point "0" "0") (point "1" "0") (point "1" "0") <)
=> `(arc (point "1" "0")
(point "1.0" "0.0")
(point "1.0" "0.0")))
;cross-product==0, angle is 0 degree
(check (std-arc-helper (point "0" "0") (point "1" "0") (point "2" "0") >)
=> `(arc (point "1" "0")
(point "1.0" "0.0")
(point "1.0" "0.0")))
(check (std-arc-helper (point "0" "0") (point "1" "0") (point "2" "0") <)
=> `(arc (point "1" "0")
(point "1.0" "0.0")
(point "1.0" "0.0")))
;cross-product==0, angle is 180 degree
(check (std-arc-helper (point "0" "0") (point "1" "0") (point "-2" "0") >)
=> `(arc (point "1" "0")
(point "0.0" "-1.0")
(point "-1.0" "0.0")))
(check (std-arc-helper (point "0" "0") (point "1" "0") (point "-2" "0") <)
=> `(arc (point "1" "0")
(point "0.0" "1.0")
(point "-1.0" "0.0")))
;cross-product!=0
(check (std-arc-helper (point "0" "0") (point "1" "0") (point "0" "1") >)
=> `(arc (point "1" "0")
(point "-0.7071067811865475" "-0.7071067811865475")
(point "0.0" "1.0")))
(check (std-arc-helper (point "0" "0") (point "1" "0") (point "0" "-1") >)
=> `(arc (point "1" "0")
(point "0.7071067811865475" "-0.7071067811865475")
(point "0.0" "-1.0")))
(check (std-arc-helper (point "0" "0") (point "1" "0") (point "0" "1") <)
=> `(arc (point "1" "0")
(point "0.7071067811865475" "0.7071067811865475")
(point "0.0" "1.0")))
(check (std-arc-helper (point "0" "0") (point "1" "0") (point "0" "-1") <)
=> `(arc (point "1" "0")
(point "-0.7071067811865475" "0.7071067811865475")
(point "0.0" "-1.0"))))

(define (test_23_27)
(test-std-arc-helper)
(check-report)
(if (check-failed?) (exit -1)))

0 comments on commit 21da23f

Please sign in to comment.