;;; ---------------------------------------------------------------------
;;;  ARCVTX-bgol.lsp
;;;  Command:  AVX
;;;
;;;  PURPOSE
;;;  For a selected filleted ARC (a rounded polyline corner), marks the
;;;  "imaginary" vertex where the two straight segments would have met
;;;  before the fillet was applied. Draws construction lines from each
;;;  tangent point on the arc to that imaginary vertex, and labels the
;;;  tangent-to-vertex distance as text.
;;;
;;;  USAGE
;;;    1. Load this file (APPLOAD or drag-drop onto the drawing window).
;;;    2. Type   AVX   at the command line and press Enter.
;;;    3. Select the arc segment (filleted corner) to analyze.
;;;    4. Two construction lines are drawn from the arc's tangent points
;;;       to the reconstructed imaginary vertex, each labeled with the
;;;       tangent-to-vertex distance. New entities are placed on layer
;;;       "BGOL-AVX".
;;;
;;;  NOTES
;;;    - Standard fillet-corner geometry: the imaginary vertex lies at
;;;      distance  radius * tan(included_angle / 2)  from each tangent
;;;      point, measured along that point's tangent direction.
;;;    - This is an original, independently written implementation.
;;;      It is INSPIRED by the general idea of fillet-corner/imaginary-
;;;      vertex reconstruction utilities common in CAD drafting
;;;      workflows, but the code, command name and file name here are
;;;      new and are NOT copied from, nor identical to, any specific
;;;      third-party product.
;;;
;;;  ---------------------------------------------------------------------
;;;  Developed and shared for the CAD community by:  BGol Community
;;;  Community website:                              https://bgol.in/
;;;  License:  Open-source & free to use, modify, and share for all.
;;;            Provided "as is", without warranty of any kind.
;;;  ---------------------------------------------------------------------

(vl-load-com)

(defun BGOL:AVX-EnsureLayer (lname / )
  (if (not (tblsearch "LAYER" lname))
    (entmake (list '(0 . "LAYER")
                   '(100 . "AcDbSymbolTableRecord")
                   '(100 . "AcDbLayerTableRecord")
                   (cons 2 lname)
                   '(70 . 0)
                   '(62 . 6)          ; magenta
                   '(6 . "Continuous")))
  )
)

(defun BGOL:AVX-MakeLine (p1 p2 lname)
  (entmake (list '(0 . "LINE")
                 '(100 . "AcDbEntity")
                 (cons 8 lname)
                 '(100 . "AcDbLine")
                 (cons 10 p1)
                 (cons 11 p2)))
)

(defun BGOL:AVX-MakeText (pt txt height lname)
  (entmake (list '(0 . "TEXT")
                 '(100 . "AcDbEntity")
                 (cons 8 lname)
                 '(100 . "AcDbText")
                 (cons 10 pt)
                 (cons 40 height)
                 (cons 1 txt)))
)

(defun C:AVX ( / ent edata obj center radius startang endang
                 incAng tanLen startpt endpt startdir enddir vertex
                 lname txtht d1 d2)
  (setq lname "BGOL-AVX")
  (BGOL:AVX-EnsureLayer lname)
  (setq ent (car (entsel "\nSelect arc: ")))
  (if ent
    (progn
      (setq edata (entget ent))
      (if (= (cdr (assoc 0 edata)) "ARC")
        (progn
          (setq obj (vlax-ename->vla-object ent))
          (setq center (vlax-get obj 'Center))
          (setq radius (vlax-get obj 'Radius))
          (setq startang (vlax-get obj 'StartAngle))
          (setq endang   (vlax-get obj 'EndAngle))
          (if (< endang startang) (setq endang (+ endang (* 2 pi))))
          (setq incAng (- endang startang))
          (setq tanLen (* radius (tan (/ incAng 2.0))))

          (setq startpt (vlax-curve-getStartPoint obj))
          (setq endpt   (vlax-curve-getEndPoint obj))

          ;; Tangent directions at each end (perpendicular to the radius)
          (setq startdir (list (- (sin startang)) (cos startang) 0.0))
          (setq enddir   (list (sin endang) (- (cos endang)) 0.0))

          ;; Imaginary vertex: extend from the start tangent point along
          ;; its tangent direction by tanLen. Both ends should converge
          ;; on (approximately) the same point.
          (setq vertex (list (+ (car startpt) (* tanLen (car startdir)))
                              (+ (cadr startpt) (* tanLen (cadr startdir)))
                              0.0))

          (setq txtht (/ radius 3.0))
          (if (< txtht 0.5) (setq txtht 0.5))

          (BGOL:AVX-MakeLine startpt vertex lname)
          (BGOL:AVX-MakeLine endpt vertex lname)

          (setq d1 (distance startpt vertex))
          (setq d2 (distance endpt vertex))

          (BGOL:AVX-MakeText
            (list (/ (+ (car startpt) (car vertex)) 2.0)
                  (/ (+ (cadr startpt) (cadr vertex)) 2.0) 0.0)
            (rtos d1 2 2) txtht lname)
          (BGOL:AVX-MakeText
            (list (/ (+ (car endpt) (car vertex)) 2.0)
                  (/ (+ (cadr endpt) (cadr vertex)) 2.0) 0.0)
            (rtos d2 2 2) txtht lname)

          (princ (strcat "\nImaginary vertex marked. Tangent distances: "
                          (rtos d1 2 2) " and " (rtos d2 2 2) "."))
        )
        (princ "\nSelected entity is not an ARC. Nothing marked.")
      )
    )
    (princ "\nNo entity selected.")
  )
  (princ)
)

(princ "\nARCVTX-bgol.lsp loaded. Type AVX to mark a filleted arc's imaginary vertex.")
(princ "\n  -- Free & open-source, courtesy of BGol Community (https://bgol.in/) --")
(princ)
