More Segment Methods


Synopsis

(std-seg->cir <seg>) ; => (midpoint radius)

(std-arc->seg <cir> <ang1> <ang2>) ; => segment

(std-arc->bul <p1> <p2> <cir> <ccw>) ; => bulge

(std-bul->ang <seg>) ; inner angle of segment

(std-arc->ang <chord> <rad>) ; inner angle of arc

(std-arclen <seg>) ; arc length

Description

These functions provide methods and conversion functions, dealing with segments and arcs.

An arc is a curved segment, defined by the circle, the start and end angle.

A circle is defined by the list of the midpoint and the radius.

STD-SEG->CIR returns the defining circle, a list of (midpoint radius). Converts a bulged segment (p1 p2 [bulge]) of a polyline to a circle (ctr rad). The start- and endpoints are known, therefore the angles too: (ANGLE ctr pt1)(ANGLE ctr pt2).

It returns nil on a straight segment.

(STD-ARC->SEG cir ang1 ang2) converts the arc given by the circle: (midpoint radius) and two angles to the segment structure (p1 p2 [bulge]).

(STD-ARC->BUL p1 p2 cir ccw) calculates the bulge (as number) from the arc, given by its endpoints and the circle and a signed number. If ccw is positive the direction is counterclockwise. Easiest is to supply a existing bulge, from which just the sign is used. This way you keep the same direction. Or use the STD-CCW function if you know a third point or any angle. See the example below.

(STD-BUL->ANG seg) returns the inner angle of the segment defined by its points and bulge, the angle from the circle midpoint to the two arc endpoints, the angle to the endpoint minus the angle to the startpoint. See also STD-SEG-BULGE-NUM.

(STD-ARC->ANG chord rad) calculates the absolute inner angle of the arc given the chord distance and radius, similar to std-bul->ang but without paying attention to the direction. The current implementation cannot calculate arc segments with 2r < chord, i.e. bulge>1, ang>180°.

(STD-ARCLEN seg) calculates arc length of the segment. This is the same as STD-SEG-LENGTH, but it works only with curved segments.

  length of arc  = radius * angle

Does NOT check for curved segment, bulge must be <> 0, otherwise you'll get 0.0 and not the straight distance.

The result may be negative, you'll probably need (abs (std-arclen seg)) instead.

What is the BULGE in a polyline segment?

The bulge is the tangent of one forth of the included angle of a curved segment. A bulge 0.0 means a straight segment. A negative number denotes a counter clockwise (CCW) direction, a positive number clockwise (CW). Together with the start- and endpoint it is sufficient information to quickly calculate all other required information of a curved segment.

         arclength = radius*angle
         bulge     = tan (ang/4)            (CCW: +, CW: -)
         angle     = 4 * atan (bulge)

bulge = (2*altitude) / chord

Examples

;;; Create a segment by 3 points

(defun geom:make-seg-3p (p1 p2 p3 / ctr)
  (if (setq ctr
        ;; circumference center
        (apply 'inters (append (geom:vec-midnorm p1 p2)
                               (geom:vec-midnorm p2 p3)
                               '(nil))))
     (std-make-seg p1 p3
       (std-arc->bul p1 p3 (list ctr)
                     (std-ccw p1 p2 p3)))
     (std-make-seg p1 p3 nil)))

;;; Generate norm vector to line p1-p2 through the midpoint

;;; as list of two arbitrary points, len: 1

;;; p1,p2 and result in current UCS (USC dependant!)

(defun geom:vec-midnorm (p1 p2 / mid ang)
  (setq mid (std-midpt p1 p2)
        ang (+ *pi/2* (angle p1 p2)))
  (list (polar mid ang 0.5)(polar mid ang -0.5)))

;;; Change startpoint of the seg by lengthening from p2 by len.

;;; Here not completely UCS independant!

(defun geom:lengthen-seg-p1  (seg len / p1 p2 cir bul)
  (if (and (minusp len) (< (std-seg-length seg) (abs len)))
    (progn (std-warn (std-msg "Segment too short")) nil)

(if (std-seg-straight-p seg) ; line segment

(std-make-seg ; polar is UCS dependent, seg is WCS

        (std-trans10 (polar (std-seg-p1-uc seg)
                            (std-seg-angle-uc seg) (- len)))
        (std-seg-p2 seg)
        nil)

;; lengthen along arc, not chord

      (progn 
        (setq p2  (std-seg-p2 seg)
              cir (std-seg->cir seg)

p1 (polar (car cir) ; polar is UCS dependent!

                         (- (angle (car cir) (std-seg-p1 seg))

;; angle = len / radius

                            (/ len (cadr cir)))
                         (cadr cir))

;; keep the same bulge sign

              bul (std-arc->bul p1 p2 cir (std-seg-bulge seg)))
        (list p1 p2 bul)))))

Arguments

seg: A segment structure, as returned by STD-MAKE-SEG. (WCS)

p1, p2: 2d or 3d points (UCS independent)

cir: A list of midpoint and radius (UCS independent)

ang1 ang2: angle numbers, defined in radians (UCS independent)

chord, rad: A distance (should be positive).

ccw: Any number, either positive or negative.

Return Value

They may return a numeric value or a segment or circle list.

Side Effects

None.

Module

(std-require 'STDPOINT)

Defined in STDPOINT

Note: Before version 0.4001 it was in STDENT!