Phần mở rộng đa giác tiếp tuyến


11

Vẽ một cái gì đó trông như thế này:

nhập mô tả hình ảnh ở đây

Nói một cách chính xác hơn, vẽ một vòng tròn bán kính r, với n đường thẳng tiếp tuyến không gian bằng nhau l. Kết nối các đầu của các đường này để tạo thành một đa giác thông thường n mặt mới.

Quy tắc

r = bán kính vòng tròn
n = số đường tiếp tuyến - phải cách đều nhau quanh đường tròn (n> = 3)
l = chiều dài cạnh của đường tiếp tuyến

Tạo một chương trình chấp nhận các đối số {r, n, l} và rút ra đầu ra cần thiết.

Đơn vị tính bằng pixel.

Không có giới hạn đối với vị trí của bản vẽ, miễn là có thể nhìn thấy tất cả.

Hình ảnh này khá tự giải thích.

Đây là mã golf, vì vậy mã ngắn nhất tính bằng byte sẽ thắng!


Tôi giả sử n sẽ> = 3, có tối đa không? Bạn có muốn các tiếp tuyến và vòng tròn là tốt?
MickyT

Có, n> = 3, (giao điểm trong ok nếu l không đủ dài). Bạn nên vẽ đường tròn và tiếp tuyến. Tôi nghĩ rằng tối đa về cơ bản là khi đầu ra là một vòng tròn bóng mờ. Nói cách khác, tối đa là tối đa thực tế cho một bản vẽ như thế này.
Căng thẳng điên cuồng

Các đơn vị pixel thậm chí áp dụng nếu chúng ta tạo ra một đồ họa vector? Bởi vì trong trường hợp như vậy, pixel thực sự khá khó xác định. Hay chúng ta phải sản xuất đồ họa rasterised?
Martin Ender

@ MartinBüttner, bạn có thể bỏ qua đơn vị pixel với đồ họa vector (ưa thích) của mình nếu có một tỷ lệ nào đó (như một trục).
Căng thẳng Maniac

Câu trả lời:


5

Toán học, 135 132 131 123 byte

{r,n,l}=Input[];Graphics[{{0,0}~Circle~r,Line[Join@@Array[{b=(a=r{c=Cos[t=2Pi#/n],s=Sin@t})-l{s,-c},a,b}&,n+1]]},Axes->1>0]

Mã này mong đợi đầu vào (thông qua một dấu nhắc) chính xác như được chỉ định trong câu hỏi: vd {100, 6, 150}. Nó tạo ra một đồ họa vector, vì vậy tôi bao gồm một trục, như được chỉ định trong các nhận xét của OP.

Cả hai tiếp tuyến và đa giác thực sự là một dải đơn, bằng cách đi qua "góc đa giác, điểm tiếp tuyến, góc đa giác, góc đa giác tiếp theo, điểm tiếp tuyến, góc đa giác ..."

nhập mô tả hình ảnh ở đây

Nếu nó không dành cho trục, tôi thậm chí có thể làm điều này trong 107 byte:

{r,n,l}=Input[];Graphics@{Circle[],Line[Join@@Array[{b=(a={c=Cos[t=2Pi#/n],s=Sin@t})-l/r{s,-c},a,b}&,n+1]]}

Tiết kiệm bổ sung (ngoài Axes->1>0) đến từ thực tế là bây giờ tôi có thể giải quyết mọi thứ bằng cách rđơn giản hóa cuộc gọi để Circlemang lại một vòng tròn đơn vị.


{0,0}~Circle~r
DavidC

@DavidCarraher heh, tôi thực sự đã thực hiện điều đó trong 135 byte, nhưng quên sao chép lại vào sổ ghi chép của mình, vì vậy nó đã được hoàn nguyên khi tôi thực hiện thay đổi Unicode. cảm ơn!
Martin Ender

8

Python, 133 byte

Câu trả lời duy nhất cho đến nay để tuân thủ quy tắc "Đơn vị tính bằng pixel" ...

from turtle import*
c=circle
r,n,l=input()
lt(90)
exec'c(r,360/n);fd(l);bk(l);'*n
fd(l)
lt(towards(-r,0)-180)
c(distance(-r,0),360,n)

Thêm exitonclick()vào cuối nếu bạn không muốn cửa sổ đóng lại ngay lập tức.

Đầu ra:

python tangentpoly.py <<< "20, 6, 30":

nhập mô tả hình ảnh ở đây

python tangentpoly.py <<< "100, 8, 200":

nhập mô tả hình ảnh ở đây


1
for i in n*[0]:c(r,360/n);fd(l);bk(l)->exec'c(r,360/n);fd(l);bk(l)'*n;
isaacg


7

T-SQL 440 483

Sẽ không giành được bất kỳ giải thưởng nào với cái này, nhưng tôi thích vẽ tranh :)

Chỉnh sửa Expletive! Chỉ cần chú ý là tôi đã nhầm lẫn với các đa giác được vẽ trên vòng tròn. Cố định với chi phí.

SELECT Geometry::UnionAggregate(Geometry::Point(0,0,0).STBuffer(@r).STExteriorRing().STUnion(Geometry::STGeomFromText(CONCAT('LINESTRING(',@r*SIN(a),' ',@r*COS(a),',',@r*SIN(a)+@l*SIN(b),' ',@r*COS(a)+@l*COS(b),')'),0))).STUnion(Geometry::ConvexHullAggregate(Geometry::Point(@r*SIN(a)+@l*SIN(b),@r*COS(a)+@l*COS(b),0)).STExteriorRing())p FROM(SELECT RADIANS(360./@*N)a,RADIANS((360./@*N)-90)b FROM(SELECT TOP(@)row_number()OVER(ORDER BY(SELECT\))-1N FROM sys.types a,sys.types b)t)r

Thực hiện với các biến sau

declare @r float = 1.0
declare @ int = 10
declare @l float = 3.0

Chạy trong Sql Server Management Studio 2012+, nó sẽ trả về các mục sau trong tab kết quả không gian. nhập mô tả hình ảnh ở đây

Với

declare @r float = 1.0
declare @ int = 360
declare @l float = 3.0

nhập mô tả hình ảnh ở đây

với

declare @r float = 10.0
declare @ int = 3
declare @l float = 10.0

nhập mô tả hình ảnh ở đây

Mở rộng ra

SELECT Geometry::UnionAggregate(    --group together lines
    Geometry::Point(0,0,0)          --Set origin
    .STBuffer(@r)                   --Buffer to @r
    .STExteriorRing()               --Make it a line
    .STUnion(                       --Join to the floowing tangent
        Geometry::STGeomFromText(   --Create a tangent line
            CONCAT('LINESTRING(',@r*SIN(a),' ',@r*COS(a),',',@r*SIN(a)+@l*SIN(b),' ',@r*COS(a)+@l*COS(b),')'),0)
        )
    ).STUnion( --Generate polygon around exterior points
    Geometry::ConvexHullAggregate(Geometry::Point(@r*SIN(a)+@l*SIN(b),@r*COS(a)+@l*COS(b),0)).STExteriorRing()
    )
    p
FROM(
    SELECT RADIANS(360./@*N)a,      --calclate bearings
        RADIANS((360./@*N)-90)b
    FROM(                           --make enough rows to draw tangents
        SELECT TOP(@)row_number()OVER(ORDER BY(SELECT\))-1N 
        FROM sys.types a,sys.types b
        )t
    )r 

5

MATLAB - 233 byte

function C(n,r,l),t=2*pi/n;c=cos(t);s=sin(t);M=[c,s;-s,c];F=@(y)cell2mat(arrayfun(@(x){M^x*y},1:n));P=F([0;r]);Q=F([l;r]);v='k';t=1e3;t=2*pi/t*(0:t);R=[1:n 1];q=Q(1,R);s=Q(2,R);plot(r*cos(t),r*sin(t),v,[P(1,R);q],[P(2,R);s],v,q,s,v);

Đầu ra chức năng mẫu cho n = 8, r = 4, l = 6(các trục được bao gồm để chỉ ra độ dài đơn vị): đầu ra

Đầu ra chức năng mẫu cho n = 1024, r = 4, l = 2: đầu ra


Tôi đang chọn nit, nhưng Đơn vị tính bằng pixel
Chấn thương kỹ thuật số

3
@DigitalTrauma: À. Không nhận thấy điều đó. Số liệu MATLAB không có đơn vị cố định; họ mở rộng ra cửa sổ. Và dù sao đó cũng là một điểm cần thiết. Giải pháp dựa trên LOGO của bạn trong Python đã đánh bại tôi một cách rõ ràng. Trước ngày hôm nay tôi đã không nghĩ ai đó sẽ chuyển LOGO thành Python, nhưng nó đây rồi. Tôi đang học khi tôi đi cùng. : P
COTO


Hình ảnh gần như là khẩu độ của logo.
tự hào

4

HTML + JavaScript (E6) 298

Để kiểm tra, lưu dưới dạng tệp html và mở bằng FireFox. Chèn các tham số r, n, l vào trường đầu vào, được phân tách bằng dấu phẩy, sau đó tab ra.

Hoặc thử jsfiddle

<input onblur="
[r,n,l]=this.value.split(','),
z=r-~l,t=D.getContext('2d'),w='lineTo',
D.width=D.height=z*2,
t.arc(z,z,r,0,7);
for(C=1,S=i=0;i++<n;)
  t[w](x=z+r*C,y=z+r*S),
  t[w](x-l*S,y+l*C),
  C=Math.cos(a=6.283*i/n),
  S=Math.sin(a),
  t[w](z+r*C-l*S,z+r*S+l*C);
t.stroke()">
<canvas id=D>

Sản lượng mẫu

50,20,140

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.