モジュール:多面体

local function create(args)
	local name=args2
	local size=tonumber(args3)
	local color=tonumber(args4)
	local dis=8
	local sf=nil
	if name=="正四面体" then
		local a=1/math.sqrt(3)
		local zp=
		local list={}
		local z=math.sqrt(2)
		local k={math.sqrt(2/3),math.sqrt(1/3)}
		for _,v in ipairs(zp) do
			local t={(v1-v2)/z,(v1+v2)/z,v3}
			table.insert(list, {t1,t2*k1-t3*k2,t2*k2+t3*k1})
		end
		sf={list,}
	elseif name=="立方体" then
		local a=1/math.sqrt(3)
		sf=
	elseif name=="正八面体" then
		sf=
	elseif name=="正十二面体" then
		local a={math.sqrt((3-math.sqrt(5))/6),math.sqrt((3+math.sqrt(5))/6),1/math.sqrt(3)}
		local zp=
		local list={}
		local z=math.sqrt(a1*a1+a2*a2)
		for _,v in ipairs(zp) do
			table.insert(list, {v1,(v2*a1-v3*a2)/z,(v2*a2+v3*a1)/z})
		end
		sf={list,}
	elseif name=="正二十面体" then
		local a={math.sqrt((5-math.sqrt(5))/10),math.sqrt((5+math.sqrt(5))/10)}
		local zp=
		local list={}
		local z=math.sqrt(a1*a1+a2*a2)
		for _,v in ipairs(zp) do
			table.insert(list, {v1,(v2*a1-v3*a2)/z,(v2*a2+v3*a1)/z})
		end
		sf={list,}
	elseif name=="切頂四面体" then
		local a={math.sqrt(2/19),math.sqrt(2/19)*3}
		local zp=
		local list={}
		local z=math.sqrt(2)
		local k={math.sqrt(2/3),math.sqrt(1/3)}
		for _,v in ipairs(zp) do
			local t={(v1-v2)/z,(v1+v2)/z,v3}
			table.insert(list, {t1,t2*k1+t3*k2,-t2*k2+t3*k1})
		end
		sf={list,}
	elseif name=="切頂六面体" then
		local b=1/math.sqrt(5-2*math.sqrt(2))
		local a={b,(math.sqrt(2)-1)*b}
		local zp={
			{a1,a2,a1},{a1,-a2,a1},{a1,a2,-a1},{a1,-a2,-a1},{-a1,a2,-a1},{-a1,-a2,-a1},{-a1,a2,a1},{-a1,-a2,a1},
			{a1,a1,a2},{a1,a1,-a2},{a1,-a1,a2},{a1,-a1,-a2},{-a1,-a1,a2},{-a1,-a1,-a2},{-a1,a1,a2},{-a1,a1,-a2},
			{a2,a1,a1},{-a2,a1,a1},{a2,a1,-a1},{-a2,a1,-a1},{a2,-a1,-a1},{-a2,-a1,-a1},{a2,-a1,a1},{-a2,-a1,a1}
		}
		local zq={
			{0,1,10,11,3,2,9,8},{1,0,16,17,6,7,23,22},{8,9,18,19,15,14,17,16},{11,10,22,23,12,13,21,20},{7,6,14,15,4,5,13,12},{2,3,20,21,5,4,19,18},
			{0,8,16},{1,22,10},{23,7,12},{6,17,14},
			{2,18,9},{3,20,11},{13,5,21},{15,19,4}
		}
		sf={zp,zq}
	elseif name=="切頂八面体" then
		local a={1/math.sqrt(5),2/math.sqrt(5)}
		sf=
	elseif name=="切頂二十面体" then
		local r=6/math.sqrt(42-2*math.sqrt(5))
		local p=(math.sqrt(5)-1)/2
		local a={r*1,r*p/3,0}
		local b={r*(p+2)/3,r*p*2/3,r*1/3}
		local c={r*(p*2+1)/3,r*p/3,r*2/3}
		local zp={
			{a1,a2,0},{a1,-a2,0},{-a1,a2,0},{-a1,-a2,0},
			{0,a1,a2},{0,a1,-a2},{0,-a1,a2},{0,-a1,-a2},
			{a2,0,a1},{-a2,0,a1},{a2,0,-a1},{-a2,0,-a1},
			{b1,b2,b3},{b1,b2,-b3},{b1,-b2,b3},{b1,-b2,-b3},{-b1,b2,b3},{-b1,b2,-b3},{-b1,-b2,b3},{-b1,-b2,-b3},
			{b3,b1,b2},{-b3,b1,b2},{b3,b1,-b2},{-b3,b1,-b2},{b3,-b1,b2},{-b3,-b1,b2},{b3,-b1,-b2},{-b3,-b1,-b2},
			{b2,b3,b1},{b2,-b3,b1},{-b2,b3,b1},{-b2,-b3,b1},{b2,b3,-b1},{b2,-b3,-b1},{-b2,b3,-b1},{-b2,-b3,-b1},
			{c1,c2,c3},{c1,c2,-c3},{c1,-c2,c3},{c1,-c2,-c3},{-c1,c2,c3},{-c1,c2,-c3},{-c1,-c2,c3},{-c1,-c2,-c3},
			{c3,c1,c2},{-c3,c1,c2},{c3,c1,-c2},{-c3,c1,-c2},{c3,-c1,c2},{-c3,-c1,c2},{c3,-c1,-c2},{-c3,-c1,-c2},
			{c2,c3,c1},{c2,-c3,c1},{-c2,c3,c1},{-c2,-c3,c1},{c2,c3,-c1},{c2,-c3,-c1},{-c2,c3,-c1},{-c2,-c3,-c1},
		}
		local zq={
			{0,13,46,44,12},{1,14,48,50,15},{2,16,45,47,17},{3,19,51,49,18},
			{4,21,54,52,20},{5,22,56,58,23},{6,24,53,55,25},{7,27,59,57,26},
			{8,29,38,36,28},{9,30,40,42,31},{10,32,37,39,33},{11,35,43,41,34},
			{0,12,36,38,14,1},{1,15,39,37,13,0},{3,18,42,40,16,2},{2,17,41,43,19,3},
			{4,20,44,46,22,5},{5,23,47,45,21,4},{6,25,49,51,27,7},{7,26,50,48,24,6},
			{8,28,52,54,30,9},{9,31,55,53,29,8},{10,33,57,59,35,11},{11,34,58,56,32,10},
			{44,20,52,28,36,12},{14,38,29,53,24,48},{49,25,55,31,42,18},{16,40,30,54,21,45},
			{13,37,32,56,22,46},{50,26,57,33,39,15},{47,23,58,34,41,17},{19,43,35,59,27,51}
		}
		local list={}
		local z=math.sqrt(p*p+1*1)
		for _,v in ipairs(zp) do
			table.insert(list, {v1,(v2*1+v3*p)/z,(-v2*p+v3*1)/z})
		end
		sf={list,zq}
	elseif name=="立方八面体" then
		local a=1/math.sqrt(2)
		local zp=
		local zq=
		sf={zp,zq}
	elseif name=="二十・十二面体" then
		local a={(1+math.sqrt(2)/(math.sqrt(3+math.sqrt(5))))/2,((math.sqrt(3-math.sqrt(5))+math.sqrt(2))/math.sqrt(3+math.sqrt(5)))/2,math.sqrt(1/(2*(3+math.sqrt(5))))}
		local zp=
		local zq=
		local list={}
		local z=math.sqrt(a1*a1+a2*a2)
		for _,v in ipairs(zp) do
			table.insert(list, {v1,(v2*a2+v3*a1)/z,(-v2*a1+v3*a2)/z})
		end
		sf={list,zq}
	elseif name=="斜方立方八面体" then
		local a={(1+math.sqrt(2))/math.sqrt(5+2*math.sqrt(2)),1/math.sqrt(5+2*math.sqrt(2))}
		sf=
	elseif name=="斜方二十・十二面体" then
		local s=math.sqrt(5)
		local n=22/math.sqrt(314+62*s)
		local a={(7-s)/22*n,(5*s+9)/22*n}
		local b={(s+4)/11*n,(s+15)/22*n}
		local c={(4+s)/11*n,(1+3*s)/22*n,(1+3*s)/11*n}
		local zp={
			{a2,a1,a1},{a2,a1,-a1},{a2,-a1,a1},{a2,-a1,-a1},{-a2,a1,a1},{-a2,a1,-a1},{-a2,-a1,a1},{-a2,-a1,-a1},
			{a1,a2,a1},{-a1,a2,a1},{a1,a2,-a1},{-a1,a2,-a1},{a1,-a2,a1},{-a1,-a2,a1},{a1,-a2,-a1},{-a1,-a2,-a1},
			{a1,a1,a2},{a1,-a1,a2},{-a1,a1,a2},{-a1,-a1,a2},{a1,a1,-a2},{a1,-a1,-a2},{-a1,a1,-a2},{-a1,-a1,-a2},
			{b2,0,b1},{b2,0,-b1},{-b2,0,b1},{-b2,0,-b1},
			{b1,b2,0},{-b1,b2,0},{b1,-b2,0},{-b1,-b2,0},
			{0,b1,b2},{0,-b1,b2},{0,b1,-b2},{0,-b1,-b2},
			{c1,c2,c3},{c1,c2,-c3},{c1,-c2,c3},{c1,-c2,-c3},{-c1,c2,c3},{-c1,c2,-c3},{-c1,-c2,c3},{-c1,-c2,-c3},
			{c3,c1,c2},{-c3,c1,c2},{c3,c1,-c2},{-c3,c1,-c2},{c3,-c1,c2},{-c3,-c1,c2},{c3,-c1,-c2},{-c3,-c1,-c2},
			{c2,c3,c1},{c2,-c3,c1},{-c2,c3,c1},{-c2,-c3,c1},{c2,c3,-c1},{c2,-c3,-c1},{-c2,c3,-c1},{-c2,-c3,-c1},
		}
		local zq={
			{0,2,3,1},{4,5,7,6},{8,10,11,9},{12,13,15,14},
			{16,18,19,17},{20,21,23,22},{0,24,2},{3,25,1},{6,26,4},{5,27,7},
			{8,28,10},{11,29,9},{14,30,12},{13,31,15},{16,32,18},{19,33,17},{22,34,20},{21,35,23},			
			{36,44,52},{37,56,46},{38,53,48},{39,50,57},{40,54,45},{41,47,58},{42,55,49},{43,51,59},
			{0,44,36,24},{25,37,46,1},{24,38,48,2},{3,50,39,25},{26,40,45,4},{5,47,41,27},{6,49,42,26},{27,43,51,7},
			{8,52,44,28},{29,45,54,9},{28,46,56,10},{11,58,47,29},{30,48,53,12},{13,55,49,31},{14,57,50,30},{31,51,59,15},
			{16,36,52,32},{33,53,38,17},{32,54,40,18},{19,42,55,33},{34,56,37,20},{21,39,57,35},{22,41,58,34},{35,59,43,23},
			{1,46,28,44,0},{2,48,30,50,3},{4,45,29,47,5},{7,51,31,49,6},
			{9,54,32,52,8},{10,56,34,58,11},{12,53,33,55,13},{15,59,35,57,14},
			{17,38,24,36,16},{18,40,26,42,19},{20,37,25,39,21},{23,43,27,41,22},
		}
		local list={}
		local p=(s-1)/2
		local z=math.sqrt(p*p+1*1)
		for _,v in ipairs(zp) do
			table.insert(list, {v1,(v2*1+v3*p)/z,(-v2*p+v3*1)/z})
		end
		sf={list,zq}
	elseif name=="斜方切頂立方八面体" then
		local v=1/math.sqrt((15-8*math.sqrt(2))/(11-6*math.sqrt(2)))
		local a={v,v/(3-math.sqrt(2)),v*(math.sqrt(2)-1)/(3-math.sqrt(2))}
		local zp={
			{a1,a2,a3},{a1,a2,-a3},{a1,-a2,a3},{a1,-a2,-a3},{a2,-a1,a3},{a2,-a1,-a3},{-a2,-a1,a3},{-a2,-a1,-a3},
			{-a1,-a2,a3},{-a1,-a2,-a3},{-a1,a2,a3},{-a1,a2,-a3},{-a2,a1,a3},{-a2,a1,-a3},{a2,a1,a3},{a2,a1,-a3},
			{a3,a1,a2},{-a3,a1,a2},{a3,a1,-a2},{-a3,a1,-a2},{a3,a2,-a1},{-a3,a2,-a1},{a3,-a2,-a1},{-a3,-a2,-a1},
			{a3,-a1,-a2},{-a3,-a1,-a2},{a3,-a1,a2},{-a3,-a1,a2},{a3,-a2,a1},{-a3,-a2,a1},{a3,a2,a1},{-a3,a2,a1},
			{a2,a3,a1},{a2,-a3,a1},{-a2,a3,a1},{-a2,-a3,a1},{-a1,a3,a2},{-a1,-a3,a2},{-a1,a3,-a2},{-a1,-a3,-a2},
			{-a2,a3,-a1},{-a2,-a3,-a1},{a2,a3,-a1},{a2,-a3,-a1},{a1,a3,-a2},{a1,-a3,-a2},{a1,a3,a2},{a1,-a3,a2},
		}
		local zq={
			{0,46,47,2,3,45,44,1},{16,14,15,18,19,13,12,17},{32,30,31,34,35,29,28,33},{8,37,36,10,11,38,39,9},{27,6,7,25,24,5,4,26},{43,22,23,41,40,21,20,42},
			{0,14,16,30,32,46},{4,2,47,33,28,26},{8,6,27,29,35,37},{12,10,36,34,31,17},
			{15,1,44,42,20,18},{3,5,24,22,43,45},{7,9,39,41,23,25},{11,13,19,21,40,38},
			{0,1,15,14},{4,5,3,2},{8,9,7,6},{10,11,13,12},
			{16,17,31,30},{20,21,19,18},{24,25,23,22},{28,29,27,26},
			{32,33,47,46},{36,37,35,34},{40,41,39,38},{44,45,43,42}
		}
		sf={zp,zq}
	elseif name=="変形立方体" then
		local a={0.251358,0.46232,0.85034}
		local zp=
		local zq=
		sf={zp,zq}
	end
	return {
		width=size,
		height=size,
		padding="strict",
		signals={
			{
				name="rot",
				init=,
				streams={
					{
						type="mousemove,touchmove",
						expr="cos(eventX()*PI/"..(size/4).."),sin(eventX()*PI/"..(size/4).."),cos(clamp((eventY()-"..(size/2)..")/"..(size/4*3)..",-1/2,1/2)*PI),sin(clamp((eventY()-"..(size/2)..")/"..(size/4*3)..",-1/2,1/2)*PI)"
					}
				}
			}
		},
		data={
			{
				name="point",
				values=sf1,
				transform={
					{
						type="formula",
						field="u",
						expr="datum0*rot00+datum1*0+datum2*rot01,-datum0*rot01*rot11+datum1*rot10+datum2*rot00*rot11,-datum0*rot01*rot10-datum1*rot11+datum2*rot00*rot10"
					},
					{
						type="formula",
						field="path",
						expr="(("..dis.."/("..dis.."-datum.u2))*datum.u0*"..(size*7/16).."+"..(size/2)..")+' '+(("..dis.."/("..dis.."-datum.u2))*datum.u1*"..(size*7/16).."+"..(size/2)..")"
					},
					{
						type="rank"
					},
					{
						type="formula",
						field="id",
						expr="datum.rank-1"
					}
				}
			},
			{
				name="map",
				values=sf2,
				transform={
					{
						type="formula",
						field="p",
						expr="datum"
					},
					{
						type="lookup",
						on="point",
						onKey="id",
						keys={"p0","p1","p2","p3","p4","p5","p6","p7"},
						as={"a","b","c","d","e","f","g","h"}
					},
					{
						type="formula",
						field="q",
						expr="datum.a,datum.b,datum.c,datum.d,datum.e,datum.f,datum.g,datum.h"
					},
					{
						type="formula",
						field="len",
						expr="datum.p.length"
					},
					{
						type="formula",
						field="path",
						expr="'M '+datum.q0.path+' L '+datum.q1.path+' L '+datum.q2.path+(datum.len<4?:(' L '+datum.q3.path))+(datum.len<5?:(' L '+datum.q4.path))+(datum.len<6?:(' L '+datum.q5.path))+(datum.len<7?:(' L '+datum.q6.path))+(datum.len<8?:(' L '+datum.q7.path))+' z'"
					},
					{
						type="formula",
						field="m",
						expr="(datum.q0.u0+datum.q1.u0+datum.q2.u0+(datum.len<4?0:datum.q3.u0)+(datum.len<5?0:datum.q4.u0)+(datum.len<6?0:datum.q5.u0)+(datum.len<7?0:datum.q6.u0)+(datum.len<8?0:datum.q7.u0))/datum.len,(datum.q0.u1+datum.q1.u1+datum.q2.u1+(datum.len<4?0:datum.q3.u1)+(datum.len<5?0:datum.q4.u1)+(datum.len<6?0:datum.q5.u1)+(datum.len<7?0:datum.q6.u1)+(datum.len<8?0:datum.q7.u1))/datum.len,(datum.q0.u2+datum.q1.u2+datum.q2.u2+(datum.len<4?0:datum.q3.u2)+(datum.len<5?0:datum.q4.u2)+(datum.len<6?0:datum.q5.u2)+(datum.len<7?0:datum.q6.u2)+(datum.len<8?0:datum.q7.u2))/datum.len"
					},
					{
						type="formula",
						field="light",
						expr="(-datum.m0-datum.m1+datum.m2)/sqrt((datum.m0*datum.m0+datum.m1*datum.m1+datum.m2*datum.m2)*3)"
					},
					{
						type="sort",
						by="m2"
					}
				}
			}
		},
		marks={
			{
				type="path",
				from={
					data="map"
				},
				properties={
					update={
						path={field="path"},
						stroke={value="black"},
						fill={
							h={value=color},
							s={value=0.9},
							l={field="light",mult=0.35,offset=0.5}
						},
						fillOpacity={value=0.9}
					}
				},
			}
		}
	}
end
return {
	_=function(frame)
		return frame:extensionTag('graph',mw.text.jsonEncode(create(frame:getParent().args)),{mode='interactive'})
	end
}