सामग्री पर जाएँ
CADCAMFUN
दस्तावेज़

दस्तावेज़

स्केच सॉल्वर

स्वतंत्रता की डिग्री, मुक्त अंक और नामित संघर्षों के साथ, लेवेनबर्ग-मार्क्वार्ट द्वारा हल किए गए प्रतिबंधित 2डी रेखाचित्र।

अंग्रेज़ी से स्वचालित रूप से अनुवादित। अंग्रेज़ी मूल देखें

सॉल्वर क्या करता है

स्केच सॉल्वर बिंदुओं, रेखाओं, वृत्तों और चापों के साथ-साथ ज्यामितीय और आयामी बाधाओं के एक सेट को ठोस निर्देशांक में बदल देता है। वो में रहता है packages/core/src/cad/sketch.ts (522 लाइनें) और से निर्यात किया जाता है @cadcamfun/core के रूप में solveSketch, sketchProfiles और polygonArea. पैरामीट्रिक इतिहास पहले अपनी अभिव्यक्तियों को संख्याओं में हल करता है, फिर सॉल्वर को कॉल करता है; हल की गई प्रोफाइल एक्सट्रूड्स, रिवॉल्व्स और पॉकेट्स को फीड करती है।

इनपुटउत्पादन
संस्थाएँ: बिंदु, रेखाएँ, वृत्त, चापहल किए गए निर्देशांक और त्रिज्या के साथ समान इकाइयाँ
बाधाएँ: 24 प्रकार, वैकल्पिक रूप से नामितस्थिति, स्वतंत्रता की डिग्री, मुक्त अंक, अनावश्यक समीकरण, संघर्ष
options: maxIterations (200), tolerance (1e-9)पुनरावृत्तियों का उपयोग किया गया और सबसे बड़ा अवशेष बचा
हल किया गया स्केच निकाला गया कक्षा में खींचें · ज़ूम करने के लिए स्क्रॉल करें · पैन करने के लिए दाईं ओर खींचें
The fully constrained 40 × 25 rectangle with a Ø10 hole at (20, 12.5), exactly as sketchProfiles returned it (the circle is a 50-point loop at the default 0.01 mm tolerance), extruded 6 mm.

डेटा मॉडल

बिंदु अज्ञात हैं. प्रत्येक रेखा, वृत्त और चाप आईडी के आधार पर बिंदुओं को संदर्भित करते हैं, इसलिए दो रेखाएं जो एक छोर साझा करती हैं, बिंदु साझा करती हैं और एक साथ चलती हैं। एक वृत्त एक और अज्ञात, उसकी त्रिज्या जोड़ता है। एक चाप एक केंद्र होता है और वृत्त पर वामावर्त दिशा में दो बिंदु होते हैं start तक end; इसकी त्रिज्या |प्रारंभ − केंद्र| और सॉल्वर अपना समीकरण रखते हुए जोड़ता है end एक ही घेरे पर.

इकाई और स्केच प्रकार (sketch.ts)
export interface SketchPoint  { id: string; kind: "point";  x: number; y: number }
export interface SketchLine   { id: string; kind: "line";   p1: PointId; p2: PointId }
export interface SketchCircle { id: string; kind: "circle"; center: PointId; radius: number }
/** Counter-clockwise from `start` to `end` about `center`. */
export interface SketchArc    { id: string; kind: "arc";    center: PointId; start: PointId; end: PointId }

export interface Sketch {
  readonly entities: ReadonlyArray<SketchEntity>
  readonly constraints: ReadonlyArray<Constraint>
}

अज्ञात वेक्टर को प्रत्येक बिंदु के रूप में रखा गया है x, y इकाई क्रम में, फिर प्रत्येक सर्कल में r. चार बिंदुओं वाले एक आयत में 8 अज्ञात हैं; अपने स्वयं के केंद्र के साथ एक वृत्त जोड़ें और इसमें 11 है।

बाधा सूची

प्रत्येक बाधा अवशिष्ट समीकरणों का योगदान करती है जो धारण करने पर शून्य होते हैं। एक बाधा एक ले जा सकती है id; बिना किसी के इसका नाम रखा गया है type#index (उदाहरण के लिए vertical#2) संघर्ष रिपोर्टों में।

प्रकारखेतअर्थसमीकरण
fixedबिंदु, एक्स?, वाई?एक बिंदु पिन करें (या तो समन्वय वैकल्पिक)1–2
coincidenta, bदो बिंदु एक हैं2
horizontal / verticalरेखाएक रेखा समतल या साहुल होती है1
horizontalPoints / verticalPointsa, bदो अंक y/x साझा करते हैं1
distanceए, बी, मूल्यबिंदु-से-बिंदु दूरी1
distanceX / distanceYए, बी, मूल्यएक अक्ष के साथ हस्ताक्षरित ऑफसेट1
lengthरेखा, मानदिशा और रेखा1
parallel / perpendiculara, bदो पंक्तियों के बीच1
equalLengtha, bदो पंक्तियाँ1
equalRadiusa, bदो वृत्त या चाप1
radius / diameterवृत्त, मानएक वृत्त या चाप का आकार1
angleए, बी, मूल्यलाइन ए से लाइन बी तक, वामावर्त, रेडियंस1
pointOnLine / pointOnCircleबिंदु, रेखा | घेराघटना1
midpointबिंदु, रेखाएक पंक्ति के मध्य में बिंदु2
symmetricए, बी, लाइनएक रेखा के चारों ओर दर्पण युग्म2
tangentLineCircleरेखा, वृत्तरेखा वृत्त को स्पर्श करती है1
tangentCirclesए, बी, आंतरिक?बाहरी r1 + r2 या आंतरिक |r1 − r2|1
concentrica, bकेंद्र मेल खाते हैं2

समाधान: लेवेनबर्ग-मार्क्वार्ट

सॉल्वर लेवेनबर्ग-मार्क्वार्ड और एक केंद्रीय-अंतर जैकोबियन के साथ वर्ग अवशेषों के योग को कम करता है। प्रत्येक चरण चोलेस्की गुणनखंडन द्वारा अवमंदित सामान्य समीकरणों को हल करता है; एक कदम जो अवशिष्ट को कम करता है उसे स्वीकार कर लिया जाता है और अवमंदन कम हो जाता है, एक ऐसा कदम जो अवशिष्ट को कम नहीं करता है उसे अस्वीकार कर दिया जाता है और अवमंदन बढ़ता है। क्योंकि प्रत्येक चरण सबसे छोटा परिवर्तन है जो अवशेषों को कम करता है, एक खींचा हुआ बिंदु शेष स्केच को उसी तरह खींचता है जैसे वह एक ड्राइंग बोर्ड पर होता है।

  1. प्रत्येक बाधा के अवशिष्ट फ़ंक्शन का निर्माण करें, और रिकॉर्ड करें कि कौन सी बाधा प्रत्येक समीकरण का स्वामी है।
  2. Start with λ = 1e-3. Solve (JᵀJ + λ·max(1, diag)) Δx = −Jᵀr; if Cholesky fails, multiply λ by 10 and retry.
  3. Accept the step if the residual norm drops (λ = max(λ/5, 1e-12)); otherwise λ ×= 10.
  4. जब अवशेष नीचे हो तो रुकें tolerance (1ई-9) या उसके बाद maxIterations (200).
  5. Analyse the Jacobian at the solution: rank by Gaussian elimination with full pivoting (tolerance 1e-7), null-space basis, free unknowns (component above 1e-6).
स्थिरकीमतकहाँ
maxIterations डिफ़ॉल्ट200SolveOptions
सहिष्णुता डिफ़ॉल्ट1e-9SolveOptions
प्रारंभिक अवमंदन λ1e-3solveSketch
गीला फर्श1e-12solveSketch
यदि शेष है तो हल किया गया ≤1e-6स्थिति
रैंक सहनशीलता1e-7nullSpace
मुक्त-अज्ञात सीमा1e-6निःशुल्क अंक
संघर्ष सीमा (प्रति समीकरण)1e-6संघर्ष

स्थिति एवं निदान

हल करने के बाद, स्वतंत्रता की डिग्री = अज्ञात - रैंक और अनावश्यक समीकरण = समीकरण - रैंक। स्थिति उन दो संख्याओं से और क्या अवशेष 1e-6 तक पहुंच गया है, से पता चलता है।

स्थितिस्थितिक्या करें
fully-constrainedहल हो गया, dof 0, कोई अतिरेक नहींकुछ नहीं
under-constrainedहल हो गया, dof > 0इसमें आईडी के लिए आयाम जोड़ें free
over-constrainedहल, निरर्थक > 0डुप्लिकेट बाधा हटाएं (हानिरहित लेकिन शोर)
conflictingहल नहीं हुआ, निरर्थक > 0में बाधा ठीक करें conflicts[0]
failedहल नहीं हुआ, कोई अतिरेक नहींइच्छित आकार के करीब से प्रारंभ करें या अधिकतम पुनरावृत्तियाँ बढ़ाएँ

These results come from running the solver on a rectangle drawn slightly askew: a(0,0) b(38,2) c(41,27) d(−1,24), with a fixed at the origin and the four lines horizontal/vertical.

वास्तविक परिणाम, प्रत्येक अतिरिक्त बाधा के अनुसार एक
// + length(l1) = 40
{"status":"under-constrained","dof":1,"free":["c","d"],"iterations":3,"redundant":0}
// + length(l2) = 25
{"status":"fully-constrained","dof":0,"iterations":3,"residual":7.95e-12,
 "points":[["a",0,0],["b",40,0],["c",40,25],["d",0,25]]}
// + length(l3) = 40   (implied by the others)
{"status":"over-constrained","dof":0,"redundant":1}
// + length(l3) = 30   named "bad"
{"status":"conflicting","redundant":1,
 "conflicts":["bad","vertical#2","length#5","vertical#4"],
 "message":"The constraints cannot all hold; the worst miss is bad"}

कम से कम परिवर्तन, कम से कम आश्चर्य नहीं

With height still free, moving c to (55, 31) and solving gave c = (40, 27.5) and d = (0, 27.5): the free height settled at the mean of the dragged c.y (31) and the old d.y (24), because Levenberg–Marquardt makes the smallest change that satisfies the constraints.

API

हस्ताक्षर
export const solveSketch: (sketch: Sketch, options?: SolveOptions) => SolveResult
export const sketchProfiles: (sketch: Sketch, tolerance?: number /* 0.01 */) =>
  { readonly loops: Vec2[][]; readonly open: Vec2[][] }
export const polygonArea: (ring: ReadonlyArray<Vec2>) => number   // positive counter-clockwise
export class SketchError extends Error {}

export interface SolveResult {
  sketch: Sketch; status: SolveStatus; dof: number; iterations: number
  residual: number          // largest absolute residual left
  free: string[]            // points and circles that can still move
  conflicts: string[]       // worst first, only when not solved
  redundant: number
  message?: string
}
एक छेद वाली प्लेट, सिरे से सिरे तक
import { solveSketch, sketchProfiles, polygonArea } from "@cadcamfun/core"

const P = (id: string, x: number, y: number) => ({ id, kind: "point" as const, x, y })
const L = (id: string, p1: string, p2: string) => ({ id, kind: "line" as const, p1, p2 })

const result = solveSketch({
  entities: [P("a", 0, 0), P("b", 38, 2), P("c", 41, 27), P("d", -1, 24),
    L("l1", "a", "b"), L("l2", "b", "c"), L("l3", "c", "d"), L("l4", "d", "a"),
    P("o", 20, 12), { id: "h", kind: "circle", center: "o", radius: 4 }],
  constraints: [
    { type: "fixed", point: "a", x: 0, y: 0 },
    { type: "horizontal", line: "l1" }, { type: "vertical", line: "l2" },
    { type: "horizontal", line: "l3" }, { type: "vertical", line: "l4" },
    { type: "length", line: "l1", value: 40 }, { type: "length", line: "l2", value: 25 },
    { type: "distanceX", a: "a", b: "o", value: 20 }, { type: "distanceY", a: "a", b: "o", value: 12.5 },
    { type: "diameter", circle: "h", value: 10 },
  ],
})
result.status                       // "fully-constrained", dof 0
const { loops } = sketchProfiles(result.sketch)
loops.map((l) => [l.length, polygonArea(l)])
// [[50, 78.333], [4, 1000]]   circle: 50 points; rectangle: 4 points, area 1000

स्केच से लेकर प्रोफाइल तक

sketchProfiles श्रृंखला रेखाओं और चापों को उनके साझा बिंदु आईडी के माध्यम से बंद लूपों में अंत से अंत तक जोड़ता है, और प्रत्येक सर्कल को अपने स्वयं के लूप के रूप में लौटाता है। एक चाप एक-दूसरे के बीच बिंदु बन जाता है ताकि जीवा भीतर ही रहे tolerance of the true arc (n = ⌈sweep / (2·acos(1 − tol/r))⌉, at least 2); a full circle gets at least 8 points. A chain that does not close is returned in open गिराए जाने के बजाय.
दो चापों और दो रेखाओं से स्लॉट कक्षा में खींचें · ज़ूम करने के लिए स्क्रॉल करें · पैन करने के लिए दाईं ओर खींचें
त्रिज्या 30 का एक 8 मिमी स्लॉट: दो चाप और दो रेखाएं अंत बिंदुओं को साझा करती हैं, स्केचप्रोफ़ाइल द्वारा एक 66-बिंदु लूप (क्षेत्र 680.739 मिमी² बनाम सटीक 681.062 मिमी²; बहुभुज अंकित है, इसलिए यह हमेशा थोड़ा छोटा होता है) में जंजीरबद्ध किया जाता है।

उपरोक्त स्लॉट को इस प्रकार हल किया गया over-constrained dof 0 और 1 निरर्थक समीकरण के साथ: बनाना top क्षैतिज का तात्पर्य तब होता है जब c1-a1 और c2-b1 ऊर्ध्वाधर होते हैं और c1, c2 एक y साझा करते हैं। समाधान अभी भी सफल होता है; स्थिति केवल डुप्लिकेट को चिह्नित करती है।

समस्या निवारण

लक्षणकारणहल करना
SketchError: Duplicate entity idदो संस्थाएं एक आईडी साझा करती हैंआईडी बिंदुओं, रेखाओं, वृत्तों और चापों में अद्वितीय हैं
SketchError: Unknown unknownएक बाधा उस बिंदु या वृत्त को नाम देती है जो वहां नहीं हैबाधा में आईडी की जाँच करें
conflicting संघर्षों की एक लंबी सूची के साथएक गलत आयाम कई समीकरणों को शून्य से दूर कर देता हैपहली प्रविष्टि ठीक करें; बाकी आमतौर पर संपार्श्विक होते हैं
failedशुरुआत किसी भी समाधान से कोसों दूर हैइच्छित आकार के करीब आएँ; अधिकतम पुनरावृत्तियाँ बढ़ाएँ
प्रोफ़ाइल गायब है loopsएक शृंखला बंद नहीं होती: वह अंदर होती है openअंतिम बिंदु साझा आईडी बनाएं, या एक संयोग बाधा जोड़ें
सर्कल में बहुत कम अंक हैंएक छोटे दायरे के लिए सहनशीलता बहुत कठिन हैस्केचप्रोफ़ाइल्स के लिए एक छोटी सहनशीलता पास करें