Beispiel #1
0
func (x *Imp) Get() Any {
	//
	if x.dp == 0 {
		ker.Stop(pack, 2)
	}
	if x.num == 0 {
		return x.empty.Clone()
	}
	if x.idx[x.dp] > 100 {
		ker.Stop(pack, 1000+x.idx[x.dp])
	}
	return x.pg[x.dp].Get(x.idx[x.dp])
}
Beispiel #2
0
// Pre: Licht n ist eingeschaltet.
// Licht n hat die Position v.
func PosLight(n uint, v *vect.Imp) {
	//
	if !lightInitialized[n] {
		ker.Stop(pack, 3)
	}
	lightSource[n].Copy(v)
}
Beispiel #3
0
// Aktuelle Ecke ist (L1, n1), postaktuelle Ecke ist (L, n).
func edge1(l Linie, n uint, l1 Linie, n1, t uint, direkt bool) {
	//
	if netz.ExPred2(func(a Any) bool { b := a.(*bahnhof.Imp); return b.Linie() == l && b.Nummer() == n },
		func(a1 Any) bool { b1 := a1.(*bahnhof.Imp); return b1.Linie() == l1 && b1.Nummer() == n1 }) {
		b, b1 := netz.Get2()
		bhf, bhf1 := b.(*bahnhof.Imp), b1.(*bahnhof.Imp)
		bhf.Umstieg()
		bhf1.Umstieg()
		netz.Put2(bhf, bhf1)
		if direkt {
			l = bhf.Linie()
		} else {
			l = Fußweg
		}
		_gleis.Def(l, t)
		netz.Edge1(_gleis)
	} else {
		if !netz.ExPred(func(a Any) bool { b := a.(*bahnhof.Imp); return b.Linie() == l && b.Nummer() == n }) {
			errh.Error2("fehlt Linie", uint(l), "Bhf", n)
		}
		if !netz.ExPred(func(a Any) bool { b := a.(*bahnhof.Imp); return b.Linie() == l1 && b.Nummer() == n1 }) {
			errh.Error2("fehlt Linie", uint(l1), "Bhf", n1)
		}
		ker.Stop(pack, 3)
	}
}
Beispiel #4
0
func Write0() {
	//
	if !initialized {
		initialize()
	}
	if !scr.UnderX() {
		ker.Stop(pack, 1)
	}
	C.glMatrixMode(C.GL_MODELVIEW)
	C.glLoadIdentity()
	for i := 0; i < 3; i++ {
		matrix[i][0] = C.GLdouble(right[i])
		matrix[i][1] = C.GLdouble(top[i])
		matrix[i][2] = C.GLdouble(-front[i])
	}
	C.glMultMatrixd(&matrix[0][0])
	C.glTranslated(C.GLdouble(-eye[0]), C.GLdouble(-eye[1]), C.GLdouble(-eye[2]))
	C.glClear(C.GL_COLOR_BUFFER_BIT + C.GL_DEPTH_BUFFER_BIT)
	for n := uint(0); n < MaxL; n++ {
		if lightInitialized[n] {
			ActualizeLight(n)
		}
	}
	C.glBegin(POINTS)
	nn = 0
}
Beispiel #5
0
func (x *Imp) PutNum(n uint) {
	//
	if n > max {
		ker.Stop(pack, 1)
	}
	x.num = n
}
Beispiel #6
0
func (x *Imp) defineSubgraph(n *node) {
	//
	n1 := n
	for n1 != x.postactual {
		if n1.predecessor == nil {
			return
		}
		n1 = n1.predecessor
	}
	for {
		n.inSubgraph = true
		if n == x.postactual {
			return
		}
		nb := n.nbPtr.nextNb
		for nb.to != n.predecessor {
			nb = nb.nextNb
			if nb == n.nbPtr {
				ker.Stop(pack, 7)
			}
		}
		nb.edgePtr.inSubgraph = true
		n = n.predecessor
	}
}
Beispiel #7
0
// Eff.: s. ins1
func insert1(l Linie, n uint, l0 Linie, n0, u, t uint) {
	//
	// aktuell: vorherige aktuelle
	netz.Reposition()
	var bhf *bahnhof.Imp
	// aktuell: vorherige aktuelle, postaktuell: alt.
	if netz.ExPred(func(a Any) bool { b := a.(*bahnhof.Imp); return b.Linie() == l0 && b.Nummer() == n0 }) {
		// aktuell: (L0, n0), postaktuell: vorherige aktuelle
		bhf = netz.Get().(*bahnhof.Imp)
	} else {
		errh.Error2("fehlt: Linie", uint(l0), "Bhf", n0)
		ker.Stop(pack, 2)
	}
	netz.Reposition()
	// aktuell: vorherige aktuelle, postaktuell: (l0, n0)
	bhf1 := bhf.Clone().(*bahnhof.Imp)
	bhf1.Numerieren(l, n)
	bhf1.Umstieg()
	netz.Ins(bhf1)
	// aktuell: (l, n), postaktuell: vorherige aktuelle
	_gleis.Def(l, t)
	netz.Edge1(_gleis)
	// verbunden: vorherige aktuelle mit (l, n), aktuell: (l, n).
	edge(l0, n0, l, n, u)
	// postaktuell: (l0, n0), aktuell: (l, n)
}
Beispiel #8
0
// Pre: d > 1, x.nbPg.GetNum() > N.
func (x *Imp) rot(d uint, right bool) {
	//
	i := x.idx[d-1]
	i1 := i
	if right { // rotation from right neighbour page to x.pg [d] on the left
		i1++
		x.pg[d].Put(x.pg[d].GetNum(), x.pg[d-1].Get(i))
		x.pg[d].IncNum()
		x.pg[d].PutPos(x.pg[d].GetNum(), x.nbPg.GetPos(0))
		x.pg[d-1].Put(i, x.nbPg.Get(0))
		x.nbPg.RotLeft()
		/********************************************************
		  // with nbPg
		      for i:= uint(1); i < num; i++ {
		        content [i - 1] = content [i]
		        pos [i - 1] = pos [i]
		      }
		      content [num - 1] = empty
		      pos [num - 1] = pos [num]
		      pos [num] = 0
		      num --
		  ********************************************************/
	} else { // rotation from left neighbour page to x.pg [d] on the right
		i1--
		if x.pg[d].GetNum() == 0 {
			ker.Stop(pack, 3)
		}
		x.pg[d].RotRight()
		/********************************************************
		  // with pg [d]
		      pos [num + 1] = pos [num]
		  //  for i:= num - 1; i >= 0; i-- { // does not work, because for uint: 0-- == 2^32 - 1  !
		      i:= num - 1
		      for {
		        content [i + 1] = content [i]
		        pos [i + 1] = pos [i]
		        if i == 0 {
		          break
		        }
		        i--
		      }
		  ********************************************************/
		x.pg[d].Put(0, x.pg[d-1].Get(i1))
		x.pg[d].PutPos(0, x.nbPg.GetPos(x.nbPg.GetNum()))
		x.pg[d].IncNum()
		x.pg[d-1].Put(i1, x.nbPg.Get(x.nbPg.GetNum()-1))
		x.nbPg.ClrLast()
		/********************************************************
		  func (x *Imp) ClrLast () {
		  // with nbPg
		      content [num - 1] = empty
		      pos [num - 1] = pos [num]
		      pos [num] = 0
		      num --
		  ********************************************************/
	}
	x.write(x.pg[d-1], x.pg[d-2].GetPos(x.idx[d-2]))
	x.write(x.pg[d], x.pg[d-1].GetPos(i))
	x.write(x.nbPg, x.pg[d-1].GetPos(i1))
}
Beispiel #9
0
func torus(x, y, z, R, r float64, c col.Colour) {
	//
	if r <= 0.0 || R <= 0.0 {
		ker.Stop(pack, 5)
	}
	for b := 0; b < N; b++ {
		s0, s1 := R+r*cos[b], R+r*cos[b+1]
		z0, z1 := z+r*sin[b], z+r*sin[b+1]
		//    v, n:= vectors (2 * N)
		for l := 0; l < N; l++ {
			quad(x+s0*cos[l], y+s0*sin[l], z0,
				x+s0*cos[l+1], y+s0*sin[l+1], z0,
				x+s1*cos[l+1], y+s1*sin[l+1], z1,
				x+s1*cos[l], y+s1*sin[l], z1, c)
			/*
			   v[2*l].Set3 (x + s0 * cos[l], y + s0 * sin[l], z0)
			   n[2*l].Set3 (1., 1., 1.)
			   v[2*l+1].Set3 (x + s0 * cos[l+1], y + s0 * sin[l+1], z0)
			   n[2*l+1].Set3 (1.0, 1.0, 1.0)
			*/
		}
		//    pts.Ins (pt.QuadStrip, 2 * N, v, n, c)
	}
	ready()
}
Beispiel #10
0
func (x *Imp) Get(p uint) Object {
	//
	if p > max+1 {
		ker.Stop(pack, 5)
	}
	return x.content[p].Clone()
}
Beispiel #11
0
func horTorus(x, y, z, R, r, a float64, f col.Colour) {
	//
	if r <= 0. || R <= 0. {
		ker.Stop(pack, 6)
	}
	for a <= -180. {
		a = a + 180.
	}
	for a >= 180. {
		a = a - 180.
	}
	s, c := math.Sin(a*um), math.Cos(a*um)
	for b := 0; b < N; b++ {
		s0, s1 := R+r*cos[b], R+r*cos[b+1]
		x0, x1 := r*sin[b], r*sin[b+1]
		for l := 0; l < N; l++ { //  x -> x * c - y * s, y -> x * s + y * c
			y00, y01 := s0*cos[l], s0*cos[l+1]
			y10, y11 := s1*cos[l], s1*cos[l+1]
			quad(x+x0*c-y00*s, y+x0*s+y00*c, z+s0*sin[l],
				x+x0*c-y01*s, y+x0*s+y01*c, z+s0*sin[l+1],
				x+x1*c-y11*s, y+x1*s+y11*c, z+s1*sin[l+1],
				x+x1*c-y10*s, y+x1*s+y10*c, z+s1*sin[l], f)
		}
	}
	ready()
}
Beispiel #12
0
func (x *Imp) DecNum() {
	//
	if x.num == 0 {
		ker.Stop(pack, 6)
	}
	x.num--
}
Beispiel #13
0
func (x *Imp) Put(p uint, o Object) {
	//
	if p > max+1 {
		ker.Stop(pack, 4)
	}
	x.content[p] = o.Clone()
}
Beispiel #14
0
func (x *Imp) GetPos(p uint) uint {
	//
	if p > max+1 {
		ker.Stop(pack, 3)
	}
	return x.pos[p]
}
Beispiel #15
0
func (x *Imp) PutPos(p, n uint) {
	//
	if p > max+1 {
		ker.Stop(pack, 2)
	}
	x.pos[p] = n
}
Beispiel #16
0
func initConsole() {
	//
	colbits := uint(0)
	XX, YY, colbits, fbmem = ker.Framebuffer()
	if fbmem == nil {
		//    terminateConsole ()
		panic("framebuffer was not initialized! (is /dev/fb0 crw-rw-rw ?)") // Speicherzugriffsfehler
	}
	maxMode = Mode(0)
	for {
		if XX == nX[maxMode] && YY == nY[maxMode] {
			mode = maxMode
			break
		} else if maxMode+1 < NModes {
			maxMode++
		} else {
			mode = defaultMode
			XX, YY = nX[mode], nY[mode]
			break
		}
	}
	switch colbits {
	case 4, 8:
		colourdepth = 1
	case 15, 16:
		colourdepth = 2
	case 24:
		colourdepth = 3
	case 32:
		colourdepth = 4
	default:
		ker.Stop(pack, 100+colbits)
	}
	col.SetColourDepth(colbits)
	fbmemsize := nY[maxMode] * nX[maxMode] * uint(colourdepth)
	if uint(len(fbmem)) != fbmemsize {
		terminateConsole()
		println("len(fbmem) == ", len(fbmem), " != fbmemsize == ", fbmemsize)
		panic("len(fbmem) not ok !")
	}
	swFontsize(font.Normal)
	fbcop = make([]byte, fbmemsize)
	archive = make([]byte, fbmemsize)
	//  for n:= 0; n < int(len(fbmem)) - int(colourdepth); n += int(colourdepth) {
	//    copy (archive[n:n+int(colourdepth)], cc (col.EncodeF))
	//  }
	emptyBackground = make([]byte, fbmemsize)
	print(esc1 + "2J" + esc1 + "?1c" + esc1 + "?25l")
	Colours(col.ScreenF, col.ScreenB)
	initMouse()
	visible = true
	go blink()
	ker.InitConsole()
	ker.SetAction(syscall.SIGUSR1, consoleOff)
	ker.SetAction(syscall.SIGUSR2, consoleOn)
	ker.InstallTerm(terminateConsole)
	go ker.CatchSignals()
	initConsoleFonts()
}
Beispiel #17
0
func Index(X Object) Object {
	//
	x, ok := X.(*page.Imp)
	if !ok {
		ker.Stop(pack, 1)
	}
	return Clone(x.Day()).(*day.Imp)
}
Beispiel #18
0
func (x *Imp) Ins(a Any) {
	//
	if !TypeEq(a, x.object) {
		ker.Stop(pack, 1)
	}
	x.num++
	x.anchor = x.anchor.Ins(a, x.num).(*heap.Imp)
	x.anchor.Lift(x.num)
}
Beispiel #19
0
func Start(x, y, z, x1, y1, z1 float64) {
	//
	if x == x1 && y == y1 && z == z1 {
		ker.Stop(pack, 4)
	}
	eye[0].Set3(x, y, z)
	focus[0].Set3(x1, y1, z1)
	Ins(pt.Start, 1, eye, focus, col.Red)
	started = true
}
Beispiel #20
0
func (x *Imp) Edge1(a Any) {
	//
	if x.Empty() || !TypeEq(a, x.edgeAnchor.attrib) ||
		x.postactual == x.actual {
		return
	}
	// simple case: actual and postactual are not yet adjacent:
	if connection(x.postactual, x.actual) == nil &&
		connection(x.actual, x.postactual) == nil {
		x.insertEdge(a)
		x.nEdges++
		return
	}
	// otherwise: an existing edge must not be cleared:
	if a == nil {
		return
	}
	// if there is an edge from postactual to actual, it is looked for:
	nb := x.postactual.nbPtr.nextNb
	for nb.to != x.actual {
		nb = nb.nextNb
		if nb == x.postactual.nbPtr {
			ker.Stop(pack, 1)
		} // not found, contradiction
	}
	// and its attrib is replaced:
	nb.edgePtr.attrib = Clone(a)
	nb.forward = true
	// in the directed case the edge goes from postactual to actual,
	// but not the other way:
	if x.directed {
		nb = x.actual.nbPtr.nextNb
		for nb.to != x.postactual {
			nb = nb.nextNb
			if nb == x.actual.nbPtr {
				ker.Stop(pack, 2)
			}
		}
		nb.forward = false
	}
}
Beispiel #21
0
func (x *Imp) Ins(a Any) {
	//
	o := a.(Object)
	if x.Ex(a) {
		return
	}
	x.ins(o, 0)
	x.num++
	x.pg[0].PutPos(1, x.num)
	for {
		if x.pg[x.dp].GetNum() <= max {
			break
		}
		// x.num == max + 1  -->  split page:
		// leave left part on x.pg [x.dp] and move right part to newPg
		x.newPg.Clr()
		x.newPg.PutNum(N)
		x.pg[x.dp].PutNum(N)
		for i := uint(0); i < N; i++ {
			x.newPg.Put(i, x.pg[x.dp].Get(N+i+1))
			x.pg[x.dp].Put(i+1+N, x.empty)
			x.newPg.PutPos(i, x.pg[x.dp].GetPos(i+1+N))
			x.pg[x.dp].PutPos(i+1+N, 0)
		}
		x.newPg.PutPos(N, x.pg[x.dp].GetPos(max+1))
		x.pg[x.dp].PutPos(max+1, 0)
		n := x.pg[x.dp-1].GetPos(x.idx[x.dp-1])
		// save middle object in b and overwrite it with x.empty:
		b := x.pg[x.dp].Get(N)
		x.pg[x.dp].Put(N, x.empty)
		x.write(x.pg[x.dp], n)
		n = x.file.Num()
		x.write(x.newPg, n)
		if x.dp == 1 { // generate new root page
			x.idx[x.dp] = 0
			x.pg[x.dp].PutNum(0)
			x.pg[x.dp].PutPos(0, x.pg[0].GetPos(0))
			x.pg[0].PutPos(0, n+1) // see above
			x.ins(b, n)
			break
		} else { // lift up former middle object
			x.dp--
			x.ins(b, n)
		}
	}
	n := x.pg[x.dp-1].GetPos(x.idx[x.dp-1])
	x.write(x.pg[x.dp], n)
	x.pg[0].PutPos(1, x.num)
	x.write(x.pg[0], 0)
	if !x.Ex(a) {
		ker.Stop(pack, 1)
	}
}
Beispiel #22
0
func (x *Imp) ExGeq(a Object) bool {
	//
	x.dp = 0
	n := x.pg[x.dp].GetPos(0)
loop:
	for {
		if x.dp >= maxDepth {
			ker.Stop(pack, 8)
		}
		x.dp++
		x.pg[x.dp] = x.read(n)
		if x.pg[x.dp].GetNum() == 0 {
			return false
		}
		x.idx[x.dp] = 0
		i1 := x.pg[x.dp].GetNum()
		for x.idx[x.dp] < i1 {
			i := (x.idx[x.dp] + i1) / 2
			if Less(x.pg[x.dp].Get(i), a) {
				x.idx[x.dp] = i + 1
			} else {
				i1 = i
			}
		}
		if x.idx[x.dp] < x.pg[x.dp].GetNum() {
			if Less(a, x.pg[x.dp].Get(x.idx[x.dp])) {
				if x.pg[x.dp].GetPos(x.idx[x.dp]) == 0 {
					return true // found next object
				} else {
					// look deeper
				}
			} else {
				return true // a.Eq (x.pg [x.dp].Get (x.idx [x.dp])
			}
		}
		n = x.pg[x.dp].GetPos(x.idx[x.dp])
		if n == 0 {
			for {
				if x.idx[x.dp] == x.pg[x.dp].GetNum() {
					if x.dp == 1 {
						return false
					} else {
						x.dp--
					}
				} else {
					break loop
				}
			}
		}
	}
	return true
}
Beispiel #23
0
// Algorithm of Dijkstra, Lit.: CLR 25.1-2, CLRS 24.2-3
// Pre: dist == inf, predecessor == nil for all nodes.
// TODO spec
func (x *Imp) searchShortestPath(p Pred) {
	//
	n := x.nodeAnchor.nextN
	set := make(nodeSet, x.nNodes)
	for i, n := 0, x.nodeAnchor.nextN; n != x.nodeAnchor; i, n = i+1, n.nextN {
		set[i] = n
	}
	sort.Sort(set)
	for len(set) > 0 {
		n = set[0]
		if len(set) == 1 {
			set = nil
		} else {
			set = set[1:]
		}
		nb := n.nbPtr.nextNb
		for nb != n.nbPtr {
			if nb.forward && nb.to != n.predecessor && p(nb.to.content) {
				var d uint
				if n.dist == inf {
					d = inf
				} else {
					d = n.dist + Val(nb.edgePtr.attrib)
				}
				if d < nb.to.dist {
					if x.demo[Breadth] {
						var nb1 *neighbour
						if nb.to.predecessor != nil {
							nb1 = nb.to.predecessor.nbPtr.nextNb
							for nb1.from != nb.to.predecessor {
								nb1 = nb1.nextNb
								if nb1.nextNb == nb1 {
									ker.Stop(pack, 6)
								}
							}
							x.write3(nb1.edgePtr.attrib, nb.to.predecessor.content, nb.to.content, false)
							x.write(nb.to.content, false)
						}
						x.write3(nb.edgePtr.attrib, n.content, nb.to.content, true)
						x.write(nb.to.content, true)
						wait()
					}
					nb.to.dist = d
					nb.to.predecessor = n
					// put the changed nb.to into the right position in set:
					sort.Sort(set)
				}
			}
			nb = nb.nextNb
		}
	}
}
Beispiel #24
0
func multipyramid(x, y, z []float64, c col.Colour) {
	//
	n := len(x)
	if n < 4 {
		ker.Stop(pack, 3)
	}
	n-- // top !
	for i := 0; i < n-1; i++ {
		triangle(x[i], y[i], z[i], x[i+1], y[i+1], z[i+1], x[n], y[n], z[n], c)
	}
	triangle(x[n-1], y[n-1], z[n-1], x[0], y[0], z[0], x[n], y[n], z[n], c)
	// bottom missing, because it need not be even
}
Beispiel #25
0
func (x *Imp) Get3() (Any, Any, Any) {
	//
	if x.actual == x.nodeAnchor {
		return nil, nil, nil
	}
	if x.actual == x.postactual {
		return nil, nil, nil
	}
	nb := x.postactual.nbPtr.nextNb
	for {
		if nb == x.postactual.nbPtr {
			ker.Stop(pack, 3)
		}
		if nb.forward && nb.to == x.actual {
			if nb.from != x.postactual {
				ker.Stop(pack, 4)
			}
			break
		}
		nb = nb.nextNb
	}
	return Clone(nb.from.content), Clone(nb.to.content), Clone(nb.edgePtr.attrib)
}
Beispiel #26
0
func Ins1(c pt.Class, a uint, v []*vect.Imp, f col.Colour) {
	//
	//  if started { ker.Stop (pack, 1) }
	if c > pt.Polygon {
		ker.Stop(pack, 2)
	}
	//  if uint(len (v)) != a { println ("pts.Ins1: len(v) = ", len(v), " != a = ", a) } // ker.Stop (pack, 98) }
	p := pt.New()
	n := vect.New()
	n.Set3(null, null, eins)
	for i := uint(0); i < a; i++ {
		p.Set(c, a-1-i, f, v[i], n)
		file.Ins(p)
	}
}
Beispiel #27
0
func vertRectangle(x, y, z, x1, y1, z1 float64, c col.Colour) {
	//
	v, n := vectors(4)
	if z == z1 {
		ker.Stop(pack, 1)
	} // horRectangle
	init4(v, n, x, y, z, x1, y1, z, x1, y1, z1, x, y, z1)
	n[1].Sub(v[1], v[0])
	n[2].Sub(v[3], v[0])
	n[0].Ext(n[1], n[2])
	n[0].Norm()
	for i := 1; i <= 3; i++ {
		n[i].Copy(n[0])
	}
	pts.Ins(pt.Quads, 4, v, n, c)
}
Beispiel #28
0
func Write(f Figure, a uint, V, N []*vect.Imp, c col.Colour) {
	//
	switch f {
	case UNDEF:
		nn = 0 // forces glEnd / glBegin
		println("gl.Write UNDEF")
		return
	case LIGHT:
		lightVis = true
		if a >= MaxL {
			ker.Stop(pack, 2)
		}
		InitLight(a, V[0], N[0], c)
		nn = 0
		println("gl.Write LIGHT")
		return
	}
	if f != fig || a != nn || nn == 0 {
		fig = f
		nn = a
		C.glEnd()
		C.glBegin(C.GLenum(f))
	}
	C.glColor3ub(C.GLubyte(c.R), C.GLubyte(c.G), C.GLubyte(c.B))
	for i := uint(0); i < a; i++ {
		println("gl.Write", i)
		vector2yyy(V[i])
		C.glVertex3dv(&yyy[0])
		vector2yyy(N[i])
		C.glNormal3dv(&yyy[0])
	}
	/*
	   tmp:= vect.New ()
	   C.glEnd ()
	   for i:= uint(0); i < a; i++ {
	     C.glBegin (LINES)
	     C.glColor3ub (C.GLubyte(0), C.GLubyte(255), C.GLubyte(0))
	     vector2yyy (V[i]); C.glVertex3dv (&yyy[0])
	     tmp.Copy (V[i])
	     tmp.Inc (N[i])
	     vector2yyy (tmp); C.glVertex3dv (&yyy[0])
	     C.glEnd ()
	   }
	   nn = 0
	   C.glBegin (POINTS)
	*/
}
Beispiel #29
0
func (x *Imp) Add(Y AdjacencyMatrix) {
	//
	y, ok := Y.(*Imp)
	if !ok {
		return
	}
	for i := uint(0); i < x.d; i++ {
		for k := uint(0); k < x.d; k++ {
			if !Eq(y.edge[i][k], x.emptyEdge) && !Eq(x.edge[i][k], y.edge[i][k]) {
				if !Eq(x.edge[i][k], x.emptyEdge) {
					ker.Stop(pack, 123456)
				}
				x.edge[i][k] = Clone(y.edge[i][k])
			}
		}
	}
}
Beispiel #30
0
func frustum(x, y, z, r, h, h1 float64, c col.Colour) {
	//
	if h1 > h {
		ker.Stop(pack, 4)
	}
	v, n := vectors(N + 2)
	v[0].Set3(x, y, h)
	n[0].Set3(0.0, 0.0, 1.0)
	for l := 0; l <= N; l++ {
		v[l+1].Set3(x+r*cos[l], y+r*sin[l], z)
		n[l+1].Set3(cos[l], sin[l], r/(h-z))
		n[l+1].Norm()
	}
	pts.Ins(pt.TriangleFan, N+2, v, n, c)
	ready()
	circle(x, y, z, -r, c)
}