Round coordinates

Round coordinates

s_velasquez
Advocate Advocate
464 Views
9 Replies
Message 1 of 10

Round coordinates

s_velasquez
Advocate
Advocate

I used the Arc method to generate 2 arcs. It turns out that the endpoints of the arcs are different than expected.
Below are the values ​​passed to the method:
"center": [ -126.429, -126.429, 0.0 ],
"radius": 177.4082,
"startAngle": 0.149527,
"endAngle": 1.42127

 

 public static Arc CreateArc(Point3d center, double radius, double startAngle, double endAngle)
  {
      return new Arc(center, radius, startAngle, endAngle);
  }

Values ​​obtained and expected at the end points of the arcs

 //Arch created
EndPoint(-100.001 48.9996 0.0)
//Expected
EndPoint(-100.0 49.0 0.0)

Arch created
EndPoint(-100.001 -49.0004 0.0)

//Expected
EndPoint(-100.0 -49.0 0.0)


Arch created
EndPoint(48.9996 -100.0 0.0)
//Expected
EndPoint(49.0 -100.0 0.0)

// Created
EndPoint(-49.0005 -100.0 0.0)
// Espected
EndPoint(-49.0 -100.0 0.0)

These differences are expected

0 Likes
Accepted solutions (2)
465 Views
9 Replies
Replies (9)
Message 2 of 10

CodeDing
Advisor
Advisor

@s_velasquez ,

 

Just because you EXPECT a result, does not mean it to be true. Did you calculate, by hand, the expected coordinates given your input values? Math is a universal language.

 

If you DESIRE your expected result, then perhaps the original method used to get the "input values" of your arc was not sufficient to achieve your end result (maybe precision was lost somewhere).

 

It appears that the Arc function is working properly given your inputs.

Does that make sense?

 

Best,

~DD

0 Likes
Message 3 of 10

s_velasquez
Advocate
Advocate

Thanks for the feedback,
I did not manually calculate the expected coordinates.
I got the values ​​for the Arc function using (entget (car (entsel))) on a drawn arc.

And the expected values ​​using (getpoint) to compare with the created arc.

That's why I called it ESPECTED and I thought the values ​​would be the same.

Message 4 of 10

ActivistInvestor
Mentor
Mentor

@s_velasquez wrote:

Thanks for the feedback,
I did not manually calculate the expected coordinates.
I got the values ​​for the Arc function using (entget (car (entsel))) on a drawn arc.

And the expected values ​​using (getpoint) to compare with the created arc.

That's why I called it ESPECTED and I thought the values ​​would be the same.


 

When LISP displays doubles on the console, it rounds them to 5 or 6 places.

To see a more precise representation of a double, pass it to (rtos <value> 2 12). 

 

For points, you can use this (courtesy of ChatGPT):

(defun point-to-string (point luprec)
   (strlcat ", "
      (mapcar 
         '(lambda (o) 
             (rtos o 2 luprec)
          )
          point
      )
   )
)

(defun strlcat (delim strlst)
   (apply 'strcat
      (cons 
         (car strlst)
         (mapcar
           '(lambda (s)
               (strcat delim s)
            )
            (cdr strlst)
         )
      )
   )
)

(defun C:PRINTCEN ( / e)
   (if (setq e (entsel "\nPick circle: "))
      (print (point-to-string (cdr (assoc 10 (entget (car e)))) 15))
   )
   (princ)
)

 

 

 

Message 5 of 10

CodeDing
Advisor
Advisor

@s_velasquez ,

 

After calculating manually, we can confirm that the numbers provided to you are correct.

I would heed @ActivistInvestor 's advice and reconsider how you achieved your initial input values. Looks like we are dealing with a loss of significant digits here.

 

Here is the manual calculation:

Start Point
x = cos(θStartAng) * radius + centerX
x = cos(0.149527) * 177.4082 + -126.429
x = cos(0.149527) * 177.4082 + -126.429
x = 0.98884165156168642801442696341599 * 177.4082 + -126.429
x = 175.4286174885859781584690616111 + -126.429
x = 48.999617488585978158469061611097
x = 48.9996
y = sin(θStartAng) * radius + centerY
y = sin(0.149527) * 177.4082 + -126.429
y = 0.14897042705435306981229529448824 * 177.4082 + -126.429
y = 26.428575316944080279873646063628 + -126.429
y = -100.00042468305591972012635393637
y = -100.0004
[48.9996,-100.0004]
End Point
x = cos(θEndAng) * radius + centerX
x = cos(1.42127) * 177.4082 + -126.429
x = 0.14896976136107304598794587223777 * 177.4082 + -126.429
x = 26.428457217497519157238698891133 + -126.429
x = 26.428457217497519157238698891133 + -126.429
x = -100.00054278250248084276130110887
x = -100.0005
y = sin(θEndAng) * radius + centerY
y = sin(1.42127) * 177.4082 + -126.429
y = 0.98884175184911409976453294502209 * 177.4082 + -126.429
y = 175.42863528039800403384621361707 + -126.429
y = 48.999635280398004033846213617068
y = 48.9996
[-100.0005,48.9996]

 

Best,

~DD

0 Likes
Message 6 of 10

s_velasquez
Advocate
Advocate

Tanks,
To get the values ​​for the 'Arc' function I also used vlax-dump-object, in the drawing of an arc.

To get the values ​​for the 'Arc' function I also used vlax-dump-object, in the drawing of an arc.

Select object:
; IAcadArc: AutoCAD Arc Interface
; Property values:
; Application (RO) = #<VLA-OBJECT IAcadApplication 00007ff7157ca058>
; ArcLength (RO) = 225.617
; Area (RO) = 4974.83
; Center = (-126.429 -126.429 0.0)
; Document (RO) = #<VLA-OBJECT IAcadDocument 0000013a9fe99448>

; EndAngle = 1.42127
; EndPoint (RO) = (-100.0 49.0 0.0)

; EntityTransparency = "ByLayer"
; Handle (RO) = "B50"
; HasExtensionDictionary (RO) = 0
; Hyperlinks (RO) = #<VLA-OBJECT IAcadHyperlinks 0000013a833597c8>
; Layer = "SGC-Conexoes (Linhas Externas)"
; Linetype = "ByLayer"
; LinetypeScale = 1.0
; Lineweight = -1
; Material = "ByLayer"
; Normal = (0.0 0.0 1.0)
; ObjectID (RO) = 53
; ObjectName (RO) = "AcDbArc"
; OwnerID (RO) = 54
; PlotStyleName = "ByLayer"

; Radius = 177.408

; StartAngle = 0.149527
; StartPoint (RO) = (49.0 -100.0 0.0)

; Thickness = 0.0
; TotalAngle (RO) = 1.27174
; TrueColor = #<VLA-OBJECT IAcadAcCmColor 0000013a9bbb4fb0>
; Visible = -1

From what I saw in @ActivistInvestor's post this is not the best way.
I need to find the best way to obtain this data.


0 Likes
Message 7 of 10

CodeDing
Advisor
Advisor
Accepted solution
(defun c:ARCINFO ( / pt2txt eSS eArc center radius startAng endAng startPt endPt str fName f)
  (defun pt2txt (pt / )
    (strcat
      "("
      (substr
        (apply 'strcat
          (mapcar
           '(lambda (n) (strcat " " (rtos n 2 15)))
            pt
          )
        )
        2
      )
      ")"
    )
  )
  (if (not (setq eSS (ssget "_+.:E:S" '((0 . "ARC")))))
    (progn (alert (princ "\nMust select ARC entity only.")) (exit))
  );if
  (setq eArc (vlax-ename->vla-object (ssname eSS 0)))
  (setq center   (vlax-get eArc 'Center)
        radius   (vlax-get eArc 'Radius)
        startAng (vlax-get eArc 'StartAngle)
        endAng   (vlax-get eArc 'EndAngle)
        startPt  (vlax-get eArc 'StartPoint)
        endPt    (vlax-get eArc 'EndPoint)
  );setq
  ;; Convert to Strings
  (setq center (pt2txt center)
        radius   (rtos radius 2 15)
        startAng (rtos startAng 2 15)
        endAng   (rtos endAng 2 15)
        startPt  (pt2txt startPt)
        endPt    (pt2txt endPt)
  );setq
  ;; Create string for file
  (setq str
    (strcat
      "Selected ARC Information"
      "\nCenter = " center
      "\nRadius = " radius
      "\nStart Angle [rad] = " startAng
      "\nEnd Angle   [rad] = " endAng
      "\nStart Point = " startPt
      "\nEnd Point   = " endPt
    );strcat
  );setq
  (setq fName (vl-filename-mktemp nil nil ".txt"))
  (setq f (open fName "w"))
  (write-line str f)
  (close f)
  (startapp "notepad" fName)
  (prompt "\nARCINFO Complete.")
  (princ)
)
0 Likes
Message 8 of 10

ActivistInvestor
Mentor
Mentor

Keep in mind that a double is limited to about 15 places of precision on both sides of the decimal point so displaying any more digits than that is entirely pointless and meaningless. 

0 Likes
Message 9 of 10

s_velasquez
Advocate
Advocate
My idea of ​​the best is exactly what you posted.
Thanks to your code I can get the data to create an arc exactly like the one selected.

I am using these values ​​in a .json file and the result is what I am looking for.

Thank you very much for your help and also for the other answers.
 
 
 
0 Likes
Message 10 of 10

ActivistInvestor
Mentor
Mentor
Accepted solution

If you need to convert to Json, you can use managed code:

 

public static class Point3dExtensions
{
    public static string ToJsonString(this Point3d point)
    {
        var coords = point.ToArray()
          .Select(o => Converter.DistanceToString(o,
              DistanceUnitFormat.Decimal, 15).TrimEnd('0'))
          .ToArray();

        return $"{{\"X\":{coords[0]},\"Y\":{coords[1]},\"Z\":{coords[2]}}}";
    }
}