ค้นหา Centroid ของรูปหลายเหลี่ยม


16

จากวิกิพีเดีย :

เซนทรอยด์ของรูปหลายเหลี่ยมที่ไม่ได้ตัดกันที่กำหนดโดยจุดยอดn ( x 0 , y 0 ), ( x 1 , y 1 ), ... , ( x n - 1 , y n − 1 ) คือ จุด ( C x , C y ) โดยที่

Formula for Centroid

และตำแหน่งAคือพื้นที่ที่ลงนามของรูปหลายเหลี่ยม

Formula for Area of Polygon

ในสูตรเหล่านี้จุดยอดจะถือว่าเป็นตัวเลขตามลำดับการเกิดขึ้นตามแนวเส้นรอบวงของรูปหลายเหลี่ยม นอกจากนี้จุดสุดยอด ( x n , y n ) จะถือว่าเป็นเช่นเดียวกับ ( x 0 , y 0 ) ความหมายi + 1บนต้องห่วงกรณีที่ผ่านมารอบ ๆ เพื่อi = 0 โปรดทราบว่าหากมีการนับคะแนนตามเข็มนาฬิกาตามลำดับพื้นที่Aซึ่งคำนวณไว้ข้างต้นจะมีเครื่องหมายลบ แต่พิกัด centroid จะถูกต้องแม้ในกรณีนี้


  • รับรายการของจุดยอดในการสั่งซื้อ (ทั้งตามเข็มนาฬิกาหรือทวนเข็มนาฬิกา) หาเซนทรอยด์ของรูปหลายเหลี่ยมที่ไม่ตัดกันตัวเองปิดแทนโดยจุดยอด
    • หากช่วยได้คุณอาจสมมติว่าอินพุตเป็น CW เท่านั้นหรือ CCW เท่านั้น พูดในคำตอบของคุณหากคุณต้องการสิ่งนี้
  • พิกัดไม่จำเป็นต้องเป็นจำนวนเต็มและอาจมีจำนวนลบ
  • ข้อมูลที่ป้อนจะถูกต้องและมีจุดยอดอย่างน้อยสามจุด
  • อินพุตต้องได้รับการจัดการที่เหมาะสมกับชนิดข้อมูลจุดลอยตัวในภาษาของคุณ
  • คุณอาจคิดว่าตัวเลขที่ป้อนจะมีจุดทศนิยมเสมอ
  • คุณอาจจะคิดว่าปลายจำนวนเต็มป้อนข้อมูลในหรือ..0
  • คุณอาจใช้ตัวเลขที่ซับซ้อนสำหรับการป้อนข้อมูล
  • ผลลัพธ์ควรมีความแม่นยำถึงหนึ่งในพันที่ใกล้ที่สุด

ตัวอย่าง

[(0.,0.), (1.,0.), (1.,1.), (0.,1.)]        -> (0.5, 0.5)
[(-15.21,0.8), (10.1,-0.3), (-0.07,23.55)]  -> -1.727 8.017
[(-39.00,-55.94), (-56.08,-4.73), (-72.64,12.12), (-31.04,53.58), (-30.36,28.29), (17.96,59.17), (0.00,0.00), (10.00,0.00), (20.00,0.00), (148.63,114.32), (8.06,-41.04), (-41.25,34.43)]   -> 5.80104769975, 15.0673812762

ดูแต่ละรูปหลายเหลี่ยมบนระนาบพิกัดวางพิกัดโดยไม่ต้องวงเล็บเหลี่ยมในเมนู "แก้ไข" ของหน้านี้

ฉันยืนยันผลลัพธ์โดยใช้เครื่องคำนวณจุดแข็งรูปหลายเหลี่ยมแบบนี้ซึ่งแย่มาก ฉันไม่พบสิ่งที่คุณสามารถป้อนจุดยอดทั้งหมดได้ในครั้งเดียวหรือไม่ได้พยายามลบ-เครื่องหมายของคุณเมื่อคุณพิมพ์ครั้งแรก ฉันจะโพสต์โซลูชัน Python ของฉันสำหรับการใช้งานของคุณหลังจากผู้คนมีโอกาสได้รับคำตอบ


เทคนิคที่ง่ายกว่ามากในการหาค่าเฉลี่ยของ x และ y สำหรับสองชุดแรก แต่ไม่ใช่ชุดที่สาม ฉันสงสัยว่าอะไรทำให้เกิดความแตกต่าง ...
ETHproductions

1
@ETHproductions รูปหลายเหลี่ยมที่สามไม่ได้นูน
JungHwan Min

1
@ETHproductions หากคุณประมาณวงกลมที่มีรูปหลายเหลี่ยมคุณสามารถย้ายจุดเฉลี่ยโดยพลการใกล้กับจุดบนวงกลมโดยใช้จุดที่อยู่ใกล้กับจุดนั้นมากขึ้นในขณะที่แทบจะไม่ส่งผลกระทบต่อ centroid และทำให้รูปหลายเหลี่ยมนูน
Christian Sievers

2
@ETHproductions จริง ๆ แล้วนูนไม่ใช่เหตุผล การเฉลี่ยxs และys ทั้งหมดให้น้ำหนักทั้งหมดในจุดยอดแทนที่จะกระจายไปทั่วร่างกาย วิธีแรกเกิดขึ้นเพราะเป็นเรื่องปกติดังนั้นทั้งสองวิธีจึงสิ้นสุดที่ศูนย์สมมาตร วิธีที่สองใช้งานได้เพราะสามเหลี่ยมทั้งสองวิธีนำไปสู่จุดเดียวกัน
Ton Hospel

1
เราสามารถใช้จำนวนเชิงซ้อนสำหรับ I / O ได้หรือไม่?
xnor

คำตอบ:


16

เยลลี่ , 25 24 22 21 18 ไบต์

S×3÷@×"
ṙ-żµÆḊçS€S

ใช้สูตรที่แสดงในปัญหา

บันทึก 3 ไบต์ด้วยความช่วยเหลือจาก @ Jonathan Allan

ลองออนไลน์!หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย

S×3÷@×"  Helper link. Input: determinants on LHS, sum of pairs on RHS
S        Sum the determinants
 ×3      Multiply by 3
     ×"  Vectorized multiply between determinants and sums
   ÷@    Divide that by the determinant sum multipled by 3 and return

ṙ-żµÆḊçS€S  Main link. Input: 2d list of points
ṙ-          Rotate the list of points by 1 to the right
  ż         Interleave those with the original points
            This creates all overlapping slices of length 2
   µ        Start new monadic chain
    ÆḊ      Get the determinant of each slice
       S€   Get the sum of each slice (sum of pairs of points)
      ç     Call the helper link
         S  Sum and return

คุณสามารถแทนที่ṁL‘$ṡ2ด้วยṙ1ż@หรือżṙ1$
Jonathan Allan

@ Jonathanathan Allan ขอบคุณฉันยังสามารถหมุนṙ-żเพื่อหลีกเลี่ยงการสลับและบันทึกไบต์อื่น
ไมล์

ใช่แน่นอน!
Jonathan Allan

17

Mathematica ขนาด 23 ไบต์

RegionCentroid@*Polygon

รับนั่นเจลลี่!

แก้ไข: ไม่มีใครชนะ Jelly ...

คำอธิบาย

Polygon

สร้างรูปหลายเหลี่ยมที่มีจุดยอดตามจุดที่ระบุ

RegionCentroid

ค้นหาเซนทรอยด์ของรูปหลายเหลี่ยม


2
คุณเอาชนะฉันได้ แต่อาจเป็นวิธีที่สั้นกว่าที่ฉันมีฉันยังไม่มีความเข้าใจที่สมบูรณ์เกี่ยวกับเยลลี่
ไมล์

3
@miles aw ... :(
JungHwan Min

4

J, 29 ไบต์

2+/@(+/\(*%3*1#.])-/ .*\)],{.

ใช้สูตรที่แสดงในปัญหา

การใช้

   f =: 2+/@(+/\(*%3*1#.])-/ .*\)],{.
   f 0 0 , 1 0 , 1 1 ,: 0 1
0.5 0.5
   f _15.21 0.8 , 10.1 _0.3 ,: _0.07 23.55
_1.72667 8.01667
   f _39 _55.94 , _56.08 _4.73 , _72.64 12.12 , _31.04 53.58 , _30.36 28.29 , 17.96 59.17 , 0 0 , 10 0 , 20 0 , 148.63 114.32 , 8.06 _41.04 ,: _41.25 34.43
5.80105 15.0674

คำอธิบาย

2+/@(+/\(*%3*1#.])-/ .*\)],{.  Input: 2d array of points P [[x1 y1] [x2 y2] ...]
                           {.  Head of P
                         ]     Get P
                          ,    Join, makes the end cycle back to the front
2                              The constant 2
2                      \       For each pair of points
                  -/ .*        Take the determinant
2    +/\                       Sum each pair of points
         *                     Multiply the sum of each pair by its determinant
          %                    Divide each by
             1#.]              The sum of the determinants
           3*                  Multiplied by 3
 +/@                           Sum and return

4

แม็กซิม่า, 124 118 116 112 106 ไบต์

f(l):=(l:endcons(l[1],l),l:sum([3,l[i-1]+l[i]]*determinant(matrix(l[i-1],l[i])),i,2,length(l)),l[2]/l[1]);

ฉันไม่เคยมีประสบการณ์กับแม็กซิม่าดังนั้นยินดีต้อนรับคำแนะนำใด ๆ

การใช้งาน:

(%i6) f([[-15.21,0.8], [10.1,-0.3], [-0.07,23.55]]);
(%o6)              [- 1.726666666666668, 8.016666666666668]

3

แร็กเก็ต 420 ไบต์

(let*((lr list-ref)(getx(lambda(i)(lr(lr l i)0)))(gety(lambda(i)(lr(lr l i)1)))(n(length l))(j(λ(i)(if(= i(sub1 n))0(add1 i))))
(A(/(for/sum((i n))(-(*(getx i)(gety(j i)))(*(getx(j i))(gety i))))2))
(cx(/(for/sum((i n))(*(+(getx i)(getx(j i)))(-(*(getx i)(gety(j i)))(*(getx(j i))(gety i)))))(* 6 A)))
(cy(/(for/sum((i n))(*(+(gety i)(gety(j i)))(-(*(getx i)(gety(j i)))(*(getx(j i))(gety i)))))(* 6 A))))
(list cx cy))

Ungolfed:

(define(f l)
  (let* ((lr list-ref)
         (getx (lambda(i)(lr (lr l i)0)))
         (gety (lambda(i)(lr (lr l i)1)))
         (n (length l))
         (j (lambda(i) (if (= i (sub1 n)) 0 (add1 i))))
         (A (/(for/sum ((i n))
                (-(* (getx i) (gety (j i)))
                  (* (getx (j i)) (gety i))))
              2))
         (cx (/(for/sum ((i n))
                 (*(+(getx i)(getx (j i)))
                   (-(*(getx i)(gety (j i)))
                     (*(getx (j i))(gety i)))))
               (* 6 A)))
         (cy (/(for/sum ((i n))
                 (*(+(gety i)(gety (j i)))
                   (-(*(getx i)(gety (j i)))
                     (*(getx (j i))(gety i)))))
               (* 6 A))))
    (list cx cy)))

การทดสอบ:

(f '[(-15.21 0.8)  (10.1 -0.3)  (-0.07 23.55)] ) 
(f '[(-39.00 -55.94)  (-56.08 -4.73)  (-72.64 12.12)  (-31.04 53.58) 
     (-30.36 28.29)  (17.96 59.17)  (0.00 0.00)  (10.00 0.00)  
     (20.00 0.00) (148.63 114.32)  (8.06 -41.04)  (-41.25 34.43)])

เอาท์พุท:

'(-1.7266666666666677 8.01666666666667)
'(5.8010476997538465 15.067381276150996)

3

R, 129 127 ไบต์

function(l){s=sapply;x=s(l,`[`,1);y=s(l,`[`,2);X=c(x[-1],x[1]);Y=c(y[-1],y[1]);p=x*Y-X*y;c(sum((x+X)*p),sum((y+Y)*p))/sum(p)/3}

ฟังก์ชั่นที่ไม่มีชื่อที่ใช้รายการ R ของรายการอันดับเป็นอินพุต ชื่อเทียบเท่าสามารถเรียกได้ว่าใช้เช่น:

f(list(c(-15.21,0.8),c(10.1,-0.3),c(-0.07,23.55)))

Ungolfed และอธิบาย

f=function(l){s=sapply;                           # Alias for sapply
              x=s(l,`[`,1);                       # Split list of tuples into vector of first elements
              y=s(l,`[`,2);                       # =||= but for second element 
              X=c(x[-1],x[1]);                    # Generate a vector for x(i+1)
              Y=c(y[-1],y[1]);                    # Generate a vector for y(i+1)
              p=x*Y-X*y;                          # Calculate the outer product used in both A, Cx and Cy
              c(sum((x+X)*p),sum((y+Y)*p))/sum(p)/3    # See post for explanation
}

ขั้นตอนสุดท้าย ( c(sum((x+X)*p),sum((y+Y)*p))/sum(p)*2/6) เป็นวิธีที่ vectorized การคำนวณทั้งสองและCx CyผลรวมในสูตรสำหรับCxและCyถูกเก็บไว้ในเวกเตอร์และจึงหารด้วย "ผลรวมใน"A *2/6เช่น:

(SUMinCx, SUMinCy) / SUMinA / 3

แล้วพิมพ์โดยปริยาย

ลองใช้กับ R-fiddle


*2/6อาจจะเป็น/3อย่างไร
mbomb007

@ mbomb007 มันชัดเจนมาก ๆ ฉันคิดว่าฉันติดอยู่กับการเล่นกอล์ฟในส่วนอื่น / ยัก
Billywob

สง่างามฉันชอบให้คุณsapplyจัดการกับรายการเหล่านั้น! อาจมีขอบเขตสำหรับการเล่นกอล์ฟที่นี่ฉันไม่แน่ใจว่าอินพุตที่อนุญาตนั้นยืดหยุ่นได้อย่างไร ถ้าคุณได้รับอนุญาตให้ป้อนข้อมูลเพียงลำดับของพิกัดเช่นc(-15.21,0.8,10.1,-0.3,-0.07,23.55)นั้นคุณสามารถบันทึก 17 y=l[s<-seq(2,sum(1|l),2)];x=l[-s];ไบต์โดยการเปลี่ยนบรรทัดแรกของฟังก์ชั่นของคุณด้วย นั่นคือการตั้งค่าyให้เป็นทุกองค์ประกอบที่จัดทำดัชนีของlและxเป็นองค์ประกอบที่จัดทำดัชนีคี่
rturnbull

ถึงแม้ว่าจะดีกว่าถ้าเราสามารถป้อนเมทริกซ์ (หรืออาร์เรย์) เช่นmatrix(c(-15.21,0.8,10.1,-0.3,-0.07,23.55),2)ถ้าเช่นนั้นจุดเริ่มต้นของฟังก์ชั่นของคุณก็จะสามารถx=l[1,];y=l[2,];ประหยัดได้ 35 ไบต์ (เมทริกซ์อินพุตสามารถเคลื่อนย้ายได้ในกรณีx=l[,1];y=l[,2];นี้) แน่นอนทางออกที่ง่ายที่สุดของทั้งหมดคือถ้าxและyจุดเป็นอินพุตเวกเตอร์แยกกันfunction(x,y)แต่ฉันไม่คิดว่ามันจะได้รับอนุญาต ...
rturnbull

@rtbull ฉันถาม OP ในความคิดเห็นและเขาต้องการเฉพาะรายการของ tuples (ไม่สะดวกมากใน R แน่นอน) ดังนั้นฉันไม่คิดว่าวิธีเมทริกซ์ได้รับอนุญาต และแม้ว่ามันจะเป็นข้อมูลที่จะต้องเป็นส่วนเวกเตอร์ (เช่นc(...)) และการแปลงเมทริกซ์จะต้องทำภายในฟังก์ชั่น
Billywob

2

Python ขนาด156 127 ไบต์

def f(p):n=len(p);p=p+p[:1];i=s=0;exec'd=(p[i].conjugate()*p[i+1]).imag;s+=d;p[i]=(p[i]+p[i+1])*d;i+=1;'*n;print sum(p[:n])/s/3

Ungolfed:

def f(points):
  n = len(points)
  points = points + [points[0]]
  determinantSum = 0
  for i in range(n):
    determinant = (points[i].conjugate() * points[i+1]).imag
    determinantSum += determinant
    points[i] = (points[i] + points[i+1]) * determinant
  print sum(points[:n]) / determinantSum / 3

ไอดีโอมัน

ซึ่งจะใช้คะแนนแต่ละคู่[x, y]เป็นจำนวนเชิงซ้อนx + y*jและส่งออกผลลัพธ์ centroid เป็นจำนวนเชิงซ้อนในรูปแบบเดียวกัน

สำหรับคู่ของจุด[a, b]และ[c, d]ค่าa*d - b*cที่จำเป็นสำหรับแต่ละจุดสามารถคำนวณได้จากดีเทอร์มีแนนต์ของเมทริกซ์

| a b |
| c d |

ใช้การคำนวณทางคณิตศาสตร์ที่ซับซ้อนค่าที่ซับซ้อนa + b*jและc + d*jสามารถใช้เป็น

conjugate(a + b*j) * (c + d*j)
(a - b*j) * (c + d*j)
(a*c + b*d) + (a*d - b*c)*j

ขอให้สังเกตว่าส่วนจินตภาพเทียบเท่ากับปัจจัย นอกจากนี้การใช้ค่าที่ซับซ้อนช่วยให้สามารถรวมคะแนนได้อย่างง่ายดายในการดำเนินการอื่น ๆ


2

R + sp (46 ไบต์)

ถือว่าspแพคเกจถูกติดตั้ง ( https://cran.r-project.org/web/packages/sp/ )

ใช้รายการจุดยอด (ตัวอย่างlist(c(0.,0.), c(1.,0.), c(1.,1.), c(0.,1.)))

ใช้ประโยชน์จากความจริงที่ว่า "labpt" ของรูปหลายเหลี่ยมคือเซนทรอยด์

function(l)sp::Polygon(do.call(rbind,l))@labpt

2

JavaScript (ES6), 102

การใช้สูตรตรงไปตรงมา

l=>[...l,l[0]].map(([x,y],i)=>(i?(a+=w=t*y-x*u,X+=(t+x)*w,Y+=(u+y)*w):X=Y=a=0,t=x,u=y))&&[X/3/a,Y/3/a]

ทดสอบ

f=
l=>[...l,l[0]].map(([x,y],i)=>(i?(a+=w=t*y-x*u,X+=(t+x)*w,Y+=(u+y)*w):X=Y=a=0,t=x,u=y))&&[X/3/a,Y/3/a]

function go()
{
  var c=[],cx,cy;
  // build coordinates array
  I.value.match(/-?[\d.]+/g).map((v,i)=>i&1?t[1]=+v:c.push(t=[+v]));
  console.log(c+''),
  [cx,cy]=f(c);
  O.textContent='CX:'+cx+' CY:'+cy;
  // try to display the polygon
  var mx=Math.max(...c.map(v=>v[0])),
    nx=Math.min(...c.map(v=>v[0])),
    my=Math.max(...c.map(v=>v[1])),
    ny=Math.min(...c.map(v=>v[1])),  
    dx=mx-nx, dy=my-ny,
    ctx=C.getContext("2d"),
    cw=C.width, ch=C.height,
    fx=(mx-nx)/cw, fy=(my-ny)/ch, fs=Math.max(fx,fy)
  C.width=cw
  ctx.setTransform(1,0,0,1,0,0);
  ctx.beginPath();
  c.forEach(([x,y],i)=>ctx.lineTo((x-nx)/fs,(y-ny)/fs));
  ctx.closePath();
  ctx.stroke();
  ctx.fillStyle='#ff0000';
  ctx.fillRect((cx-nx)/fs-2,(cy-ny)/fs-2,5,5);
}
go()
#I { width:90% }
#C { width:90%; height:200px;}
<input id=I value='[[-15.21,0.8], [10.1,-0.3], [-0.07,23.55]]'>
<button onclick='go()'>GO</button>
<pre id=O></pre>
<canvas id=C></canvas>


1

Python 2, 153 ไบต์

ไม่ใช้ตัวเลขที่ซับซ้อน

P=input()
A=x=y=0;n=len(P)
for i in range(n):m=-~i%n;a=P[i][0];b=P[i][1];c=P[m][0];d=P[m][1];t=a*d-b*c;A+=t;x+=t*(a+c);y+=t*(b+d)
k=1/(3*A);print x*k,y*k

ลองออนไลน์

Ungolfed:

def centroid(P):
    A=x=y=0
    n=len(P)
    for i in range(n):
        m=-~i%n
        x0=P[i][0];y0=P[i][1]
        x1=P[m][0];y1=P[m][1]
        t = x0*y1 - y0*x1
        A += t/2.
        x += t * (x0 + x1)
        y += t * (y0 + y1)
    k = 1/(6*A)
    x *= k
    y *= k
    return x,y

1

ที่จริงแล้ว45 40 39 ไบต์

นี้ใช้อัลกอริทึมที่คล้ายกับคำตอบของวุ้นไมล์ มีวิธีที่สั้นกว่าในการคำนวณดีเทอร์มิแนนต์โดยใช้ผลิตภัณฑ์ดอท ยินดีต้อนรับคำแนะนำการเล่นกอล์ฟ ลองออนไลน์!

;\Z♂#;`i¥`M@`i│N@F*)F@N*-`M;Σ3*)♀*┬♂Σ♀/

Ungolfing

         Implicit input pts.
;\       Duplicate pts, rotate right.
Z        Zip rot_pts and pts together.
♂#       Convert the iterables inside the zip to lists
         (currently necessary due to a bug with duplicate)
;        Duplicate the zip.
`...`M   Get the sum each pair of points in the zip.
  i        Flatten the pair to the stack.
  ¥        Pairwise add the two coordinate vectors.
@        Swap with the other zip.
`...`M   Get the determinants of the zip.
  i│       Flatten to stack and duplicate entire stack.
           Stack: [a,b], [c,d], [a,b], [c,d]
  N@F*)    Push b*c and move it to BOS.
  F@N*     Push a*d.
  -        Get a*d-b*c.
;Σ3*)    Push 3 * sum(determinants) and move it to BOS.
♀*       Vector multiply the determinants and the sums.
┬        Transpose the coordinate pairs in the vector.
♂Σ       Sum the x's, then the y's.
♀/       Divide the x and y of this last coordinate pair by 3*sum(determinants).
         Implicit return.

รุ่นที่สั้นกว่าและไม่สามารถแข่งขันได้

นี่เป็นอีกรุ่น 24 ไบต์ที่ใช้หมายเลขที่ซับซ้อน มันไม่ใช่การแข่งขันเพราะต้องอาศัยการแก้ไขข้อบกพร่องที่โพสต์วันที่ความท้าทายนี้ ลองออนไลน์!

;\│¥)Z`iá*╫@X`M;Σ3*)♀*Σ/

Ungolfing

         Implicit input a list of complex numbers, pts.
;\       Duplicate pts, rotate right.
│        Duplicate stack. Stack: rot_pts, pts, rot_pts, pts.
¥)       Pairwise sum the two lists of points together and rotate to BOS.
Z        Zip rot_pts and pts together.
`...`M   Map the following function over the zipped points to get our determinants.
  i        Flatten the list of [a+b*i, c+d*i].
  á        Push the complex conjugate of a+bi, i.e. a-b*i.
  *        Multiply a-b*i by c+d*i, getting (a*c+b*d)+(a*d-b*c)*i.
           Our determinant is the imaginary part of this result.
  ╫@X      Push Re(z), Im(z) to the stack, and immediately discard Re(z).
           This map returns a list of these determinants.
;        Duplicate list_determinants.
Σ3*)     Push 3 * sum(list_determinants) and rotate that to BOS.
♀*Σ      Pairwise multiply the sums of pairs of points and the determinants and sum.
/        Divide that sum by 3*sum(list_determinants).
         Implicit return.

1

C ++ 14, 241 ไบต์

struct P{float x;float y;};
#define S(N,T)auto N(P){return 0;}auto N(P a,P b,auto...V){return(T)*(a.x*b.y-b.x*a.y)+N(b,V...);}
S(A,1)S(X,a.x+b.x)S(Y,a.y+b.y)auto f(auto q,auto...p){auto a=A(q,p...,q)*3;return P{X(q,p...,q)/a,Y(q,p...,q)/a};}

เอาต์พุตเป็นโครงสร้างตัวช่วย P ,

Ungolfed:

 //helper struct
struct P{float x;float y;};

//Area, Cx and Cy are quite similar
#define S(N,T)\  //N is the function name, T is the term in the sum
auto N(P){return 0;} \   //end of recursion for only 1 element
auto N(P a,P b,auto...V){ \ //extract the first two elements
  return (T)*(a.x*b.y-b.x*a.y) //compute with a and b
         + N(b,V...); \        //recursion without first element
}

//instantiate the 3 formulas
S(A,1)
S(X,a.x+b.x)
S(Y,a.y+b.y)


auto f(auto q,auto...p){
  auto a=A(q,p...,q)*3; //q,p...,q appends the first element to the end
  return P{X(q,p...,q)/a,Y(q,p...,q)/a};
}

การใช้งาน:

f(P{0.,0.}, P{1.,0.}, P{1.,1.}, P{0.,1.})
f(P{-15.21,0.8}, P{10.1,-0.3}, P{-0.07,23.55})

1

Clojure, 177 156 143 ไบต์

อัปเดต: แทนที่จะโทรกลับฉันใช้[a b c d 1]เป็นฟังก์ชันและอาร์กิวเมนต์เป็นเพียงรายการดัชนีสำหรับเวกเตอร์นี้ ถูกนำมาใช้เป็นค่าแมวมองเมื่อคำนวณ1A

การปรับปรุงที่ 2: ไม่ precalculating Aที่letใช้(rest(cycle %))จะได้รับการป้อนข้อมูลเวกเตอร์ชดเชยโดยหนึ่ง

#(let[F(fn[I](apply +(map(fn[[a b][c d]](*(apply +(map[a b c d 1]I))(-(* a d)(* c b))))%(rest(cycle %)))))](for[i[[0 2][1 3]]](/(F i)(F[4])3)))

รุ่นเดิม:

#(let[F(fn[L](apply +(map(fn[[a b][c d]](*(L[a b c d])(-(* a d)(* c b))))%(conj(subvec % 1)(% 0)))))A(*(F(fn[& l]1))3)](map F[(fn[v](/(+(v 0)(v 2))A))(fn[v](/(+(v 1)(v 3))A))]))

ที่ระยะตีกอล์ฟน้อย:

(def f (fn[v](let[F (fn[l](apply +(map
                                    (fn[[a b][c d]](*(l a b c d)(-(* a d)(* c b))))
                                    v
                                    (conj(subvec v 1)(v 0)))))
                  A (* (F(fn[& l] 1)) 3)]
                [(F (fn[a b c d](/(+ a c)A)))
                 (F (fn[a b c d](/(+ b d)A)))])))

สร้างฟังก์ชั่นผู้ช่วยซึ่งดำเนินการบวกกับการติดต่อกลับใดFlสำหรับAการโทรกลับจะกลับมาอย่างต่อเนื่อง1ในขณะที่พิกัด X และ Y มีฟังก์ชั่นของตัวเอง (conj(subvec v 1)(v 0))หยดองค์ประกอบแรกและผนวกไปยังจุดสิ้นสุดด้วยวิธีนี้มันเป็นเรื่องง่ายที่จะติดตามและx_i อาจจะยังคงมีการทำซ้ำบางส่วนจะถูกกำจัดโดยเฉพาะอย่างยิ่งที่ผ่านมาx_(i+1)(map F[...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.