贝塞尔曲面的绘制

引言

网上很少有贝塞尔曲面运算的例子,大多都是OpenGL的,我自己写了一个,共需要的朋友参考一下o(∩_∩)o...

思路

截图

代码

package  com.cg4hj.chapter05.beziersurface;

import  java.awt.Canvas;
import  java.awt.Dimension;
import  java.awt.Graphics;
import  java.awt.event.MouseAdapter;
import  java.awt.event.MouseEvent;
import  java.awt.event.WindowAdapter;
import  java.awt.event.WindowEvent;

import  javax.swing.JFrame;

import  com.cg4hj.utils.Point3D;


@SuppressWarnings(
" serial " )
public   class  BezierSurface  extends  JFrame  {

    
public BezierSurface() {
        
super("Bezier Surfaces");
        addWindowListener(
new WindowAdapter() {
            
public void windowClosing(WindowEvent evt) {
                System.exit(
0);
            }

        }
);
        add(
"Center"new CvBezierSurface());
        setSize(
800,600);
        setVisible(
true);
    }

    
    
public static void main(String[] args) {
        
new BezierSurface();
    }


}


@SuppressWarnings(
" serial " )
class  CvBezierSurface  extends  Canvas  {
    
private int maxX, maxY;
    
private double rWidth = 10.0D;
    
private double rHeight = 10.0D;
    
private double pixelWidth, pixelHeight;
    
    
private int srcCount = 4;
    
private int dstCount = 40;
    
    
private Point3D[][] src = new Point3D[srcCount][srcCount];
    
private Point3D[][] dst = new Point3D[dstCount][dstCount];
    
    
{
        
for (int i = 0; i < srcCount; i++{
            
for (int j = 0; j < srcCount; j++{
                src[i][j] 
= new Point3D();
            }

        }

        
for (int i = 0; i < dstCount; i++{
            
for (int j = 0; j < dstCount; j++{
                dst[i][j] 
= new Point3D();
            }

        }

    }

    
    
private void initps() {
        
for (int i = 0; i < srcCount; i++{
            
for (int j = 0; j < srcCount; j++{
                src[i][j].x 
= random();
                src[i][j].y 
= random();
                src[i][j].z 
= random();
            }

        }
        
    }

    
    
private double random() {
        
return Math.random() * 10;
    }

    
    
public CvBezierSurface() {
        addMouseListener(
new MouseAdapter() {
            
public void mousePressed(MouseEvent evt) {
                repaint();
            }

        }
);
    }

    
    
private int iX(double x) {
        
return (int)Math.round(x / pixelWidth);
    }

    
    
private int iY(double y) {
        
return (int)Math.round(maxY - y / pixelHeight);
    }

    
    
private void initgr() {
        Dimension d 
= getSize();
        maxX 
= d.width - 1;
        maxY 
= d.height - 1;
        pixelWidth 
= rWidth / maxX;
        pixelHeight 
= rHeight / maxY;
    }

    
    
public void paint(Graphics g) {
        initgr();
        initps();
        
int left = iX(0), right = iX(rWidth),
            bottom 
= iY(0), top = iY(rHeight);
        g.drawRect(left, top, right 
- left, bottom - top);
        drawBezierSurface();    
    }

    
    
private void drawBezierSurface() {
        
        Graphics g 
= getGraphics();
        
        
double mui, muj, bi = 0, bj = 0;
        
for (int i = 0; i < dstCount; i++{
            mui 
= (i) / (double)(dstCount - 1);
            
for (int j = 0; j < dstCount; j++{
                muj 
= (j) / (double)(dstCount - 1);
                dst[i][j].x 
= 0;
                dst[i][j].y 
= 0;
                dst[i][j].z 
= 0;
                
for (int ki = 0; ki < srcCount; ki++{
                    bi 
= bezierBlendFunction(ki,mui,srcCount - 1);
                    
for (int kj = 0; kj < srcCount; kj++{
                        bj 
= bezierBlendFunction(kj,muj,srcCount - 1);
                        dst[i][j].x 
+= (src[ki][kj].x * bi * bj);
                        dst[i][j].y 
+= (src[ki][kj].y * bi * bj);
                        dst[i][j].z 
+= (src[ki][kj].z * bi * bj);
                    }

                }

            }

        }

        
        
for (int i = 0; i < dstCount; i++{
            
for (int j = 0; j < dstCount; j++{
                
if (j != dstCount - 1{
                    g.drawLine(iX(dst[i][j].x), iY(dst[i][j].y), iX(dst[i][j
+1].x), iY(dst[i][j+1].y));
                }

                
if (i != dstCount - 1{
                    g.drawLine(iX(dst[i][j].x), iY(dst[i][j].y), iX(dst[i 
+ 1][j].x), iY(dst[i + 1][j].y));
                }

            }

        }

        
    }

    
    
private double bezierBlendFunction(int k, double mu, int n) {
        
int nn = n, kn = k, nkn = n - k;
        
double blend = 1;
        
        
while (nn >= 1{
            blend 
*= nn;
            nn 
= nn - 1;
            
if (kn > 1{
                blend 
/= (double)kn;
                kn
--;
            }

            
if (nkn > 1{
                blend 
/= (double)nkn;
                nkn
--;
            }

        }
            
        
if (k > 0{
            blend 
*= Math.pow(mu, (double)k);
        }

        
if (n - k > 0{
            blend 
*= Math.pow(1 - mu, (double)(n - k)); 
        }

        
return blend;
    }

    
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值