Slower rendering when using paths - winforms

Why does the following code render much more slowly when using a path as opposed to drawing each line individually?
If I draw each line individually, window resizing seems ok, but if I use a path, the resizing is very laggy.
public class GdiRenderCanvas : System.Windows.Forms.Control
{
System.Drawing.Drawing2D.GraphicsPath path = null;
public GdiRenderCanvas()
{
SetStyle(System.Windows.Forms.ControlStyles.AllPaintingInWmPaint | System.Windows.Forms.ControlStyles.UserPaint, true);
DoubleBuffered = true;
ResizeRedraw = true;
path = new System.Drawing.Drawing2D.GraphicsPath();
Random r = new Random(8);
for (int i = 0; i < 1000; ++i)
{
int x = (int)(r.NextDouble() * 800);
int y = (int)(r.NextDouble() * 800);
int x1 = (int)(r.NextDouble() * 800);
int y1 = (int)(r.NextDouble() * 800);
path.AddLine(x, y, x1, y1);
path.CloseFigure();
}
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;
if (false)
{
Random r = new Random(8);
for (int i = 0; i < 1000; ++i)
{
int x = (int)(r.NextDouble() * 800);
int y = (int)(r.NextDouble() * 800);
int x1 = (int)(r.NextDouble() * 800);
int y1 = (int)(r.NextDouble() * 800);
e.Graphics.DrawLine(pen, x, y, x1, y1);
}
}
else
{
e.Graphics.DrawPath(pen, path);
}
}
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Red, 1);
}

Related

Looping a mouse movement in Processing

I am trying to de-pixellate an image over time, which is working. However when this has finished, I want the mouse to go back to its original point and start again, forever. I have tried loop commands with no luck.
I can only get this code to work in version 2.2.1
import java.awt.Robot;
PImage img;
int pixls = 0;
int x, y, yinc;
int XOffset = 0;
int YOffset = 30;
int counter = YOffset;
Robot robot;
void setup() {
size(900, 900);
//noCursor();
noStroke();
img = loadImage("p.jpg");
img.resize(900, 900);
//surface.setLocation(XOffset, YOffset);
}
void draw() {
loadPixels();
frameRate(14);
pixls = (int)map(mouseY, height, 20, 250, 20); //pixellation
for (int i = 0; i < pixls; i++) {
for (int j = 0; j < pixls; j++) {
float r = red(img.pixels[(height/pixls)*j*width+(width/pixls)*i]);
float g = green(img.pixels[(height/pixls)*j*width+(width/pixls)*i]);
float b = blue(img.pixels[(height/pixls)*j*width+(width/pixls)*i]);
fill(r, g, b);
rect((width/pixls)*i, (height/pixls)*j, width/pixls, height/pixls);
yinc = (height/pixls)*j;
}
}
try {
robot = new Robot();
robot.mouseMove(XOffset*2, counter); //counter is start of mouse
if (counter > height + YOffset)
{
counter = YOffset + 30; // +30 for menubar
}
}
catch (Exception e) {
//println("error = ", e);
}
counter++;
}
The following should work in Processing 2.2.1. It uses an old method for finding the XOffset and YOffset of the app's window.
/*
Will work in Processing 2.2.1
*/
import java.awt.Robot;
Robot robot;
PImage img;
int pixls = 0;
int x, y, yinc;
int XOffset = 0;
int YOffset = 0;
int counter = 0;
void setup() {
size(710, 710);
// noCursor();
noStroke();
img = loadImage("myImage.jpg");
img.resize(710, 710);
}
void draw() {
int XOffset = frame.getLocationOnScreen().x;
int YOffset = frame.getLocationOnScreen().y;
pixls = (int)map(mouseY, 0, height, 5, 350);
for (int i = 0; i < pixls; i++) {
for (int j = 0; j < pixls; j++) {
float r = red(img.pixels[(height/pixls)*j*width+(width/pixls)*i]);
float g = green(img.pixels[(height/pixls)*j*width+(width/pixls)*i]);
float b = blue(img.pixels[(height/pixls)*j*width+(width/pixls)*i]);
fill(r, g, b);
rect((width/pixls)*i, (height/pixls)*j, width/pixls, height/pixls);
yinc = (height/pixls)*j;
}
}
try {
robot = new Robot();
robot.mouseMove(XOffset + 10, counter);
if (counter > height + YOffset + 30) {
counter = YOffset + 30; // + 30 for menubar
}
} catch (Exception e) {
println("error = ", e);
}
counter++;
}

Processing - Flock Boids avoid draggable objects

I'm working on a boids flocking project.
My goal is to have several draggable objects which have to be avoided by the boids.
There are several different flocks with a different starting position.
I managed to get the boids to avoid one draggable object. But I can't seem to make them avoid all. (using a for loop)
I really can't figure out why this won't do the trick..
I hope you could give me some suggestions.
the code:
int initBoidNum = 100; //amount of boids to start the program with
BoidList flock1, flock2, flock3;
Draggable draggable;
NullDraggableObject nullDraggableObject;
ArrayList draggables;
int id;
float[] xposs= new float[10];
float[] yposs= new float[10];
String turn;
void setup() {
size(1000, 700);
//create and fill the list of boids
flock1 = new BoidList(150, 0, 10, 100);
flock2 = new BoidList(150, 255, 10, 200);
flock3 = new BoidList(150, 150, 10, 300);
turn = "turn";
nullDraggableObject = new NullDraggableObject();
draggables = new ArrayList();
for (int i = 0; i < 10; i++) {
draggables.add(new DraggableObject(random(width), random(height/2)));
}
}
void draw() {
background(100, 60);
flock1.run();
flock2.run();
flock3.run();
stroke(255);
noFill();
draggable = nullDraggableObject;
for (id = 0; id < draggables.size (); id++) {
Draggable d = (Draggable)draggables.get(id);
d.draw();
if (d.isBeingMouseHovered()) {
draggable = d;
}
}
}
void mousePressed() {
draggable.mousePressed();
}
void mouseDragged() {
draggable.mouseDragged();
}
void mouseReleased() {
draggable.mouseReleased();
}
interface Draggable {
boolean isBeingMouseHovered();
boolean inside(float ix, float iy);
void draw();
void mousePressed();
void mouseDragged();
void mouseReleased();
}
class NullDraggableObject implements Draggable {
boolean isBeingMouseHovered() {
return false;
}
boolean inside(float ix, float iy) {
return false;
}
void draw() {
}
void mousePressed() {
}
void mouseDragged() {
}
void mouseReleased() {
}
}
public class DraggableObject implements Draggable {
float XX, YY;
float radius;
boolean drag;
float dragX, dragY;
DraggableObject(float _x, float _y) {
XX = _x;
YY = _y;
radius = 50;
drag = false;
dragX = 0;
dragY = 0;
}
boolean isBeingMouseHovered() {
return inside(mouseX, mouseY);
}
boolean inside(float ix, float iy) {
return (dist(XX, YY, ix, iy) < radius);
}
void draw() {
ellipseMode(CENTER);
ellipse(XX, YY, 2*radius, 2*radius);
String space = "__";
println(id);
println(XX);
println(YY);
xposs[id] = XX;
yposs[id] = YY;
}
void mousePressed() {
drag = inside(mouseX, mouseY);
if (drag) {
dragX = mouseX - XX;
dragY = mouseY - YY;
}
}
void mouseDragged() {
if (drag) {
XX = mouseX - dragX;
YY = mouseY - dragY;
}
}
void mouseReleased() {
drag = false;
}
}
class Boid {
//fields
PVector pos, vel, acc, ali, coh, sep; //pos, velocity, and acceleration in a vector datatype
float neighborhoodRadius; //radius in which it looks for fellow boids
float maxSpeed = 1; //maximum magnitude for the velocity vector
float maxSteerForce = .05; //maximum magnitude of the steering vector
float sMod, aMod, cMod; //modifiers for the three forces on the boid
float h; //hue
Boid(PVector inPos) {
pos = new PVector();
pos.set(inPos);
vel = new PVector(random(-1, 1), random(-1, 1));
acc = new PVector(0, 0);
neighborhoodRadius = 20;
sMod = 1;
aMod = 1;
cMod = 4;
}
Boid(PVector inPos, PVector inVel, float r) {
pos = new PVector();
pos.set(inPos);
vel = new PVector();
vel.set(inVel);
acc = new PVector(0, 0);
neighborhoodRadius = r;
}
void run(ArrayList bl) {
for (int i =0; i < 10; i++) {
acc.add(attract(new PVector(width/2, height/2), true));
acc.add(avoid(new PVector(xposs[i], yposs[i]), true));
if (i == 10) i = 0;
}
if (pos.x>width-10)acc.add(bounce(new PVector(width, pos.y), true));
if (pos.x<10) acc.add(bounce(new PVector(0, pos.y), true));
if (pos.y>height-10) acc.add(bounce(new PVector(pos.x, height), true));
if (pos.y<10) acc.add(bounce(new PVector(pos.x, 0), true));
ali = alignment(bl);
coh = cohesion(bl);
sep = seperation(bl);
for (int i =0; i < 10; i++) {
if (PVector.dist(new PVector(xposs[i], yposs[i]), pos)>180) {
acc.add(PVector.mult(ali, aMod));
acc.add(PVector.mult(coh, cMod));
acc.add(PVector.mult(sep, sMod));
}
if (PVector.dist(new PVector(xposs[i], yposs[i]), pos)<80) maxSpeed = 1000;
if (i == 10) i = 0;
}
if (PVector.dist(new PVector(width, height), pos)<60) maxSpeed = 1000;
if (PVector.dist(new PVector(0, 0), pos)<50) {
maxSpeed = 1000;
} else {
maxSpeed = 1;
}
move();
checkBounds();
render();
}
void move() {
vel.add(acc); //add acceleration to velocity
vel.limit(maxSpeed); //make sure the velocity vector magnitude does not exceed maxSpeed
pos.add(vel); //add velocity to position
acc.mult(0); //reset acceleration
}
void checkBounds() {
}
void render() {
pushMatrix();
translate(pos.x, pos.y);
rotate(atan2(vel.y, vel.x)); //rotate drawing matrix to direction of velocity
stroke(0);
noFill();
ellipse(0, 0, neighborhoodRadius/2, neighborhoodRadius/2);
noStroke();
fill(h);
//draw triangle
beginShape(TRIANGLES);
rect(0, 0, 6, 2);
endShape();
popMatrix();
}
//steering. If arrival==true, the boid slows to meet the target. Credit to Craig Reynolds
PVector steer(PVector target, boolean arrival) {
PVector steer = new PVector(); //creates vector for steering
if (!arrival) {
steer.set(PVector.sub(target, pos)); //steering vector points towards target (switch target and pos for avoiding)
steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
} else {
PVector targetOffset = PVector.sub(target, pos);
float distance=targetOffset.mag();
float rampedSpeed = maxSpeed*(distance/100);
float clippedSpeed = min(rampedSpeed, maxSpeed);
PVector desiredVelocity = PVector.mult(targetOffset, (clippedSpeed/distance));
steer.set(PVector.sub(desiredVelocity, vel));
}
return steer;
}
//avoid. If weight == true avoidance vector is larger the closer the boid is to the target
PVector avoid(PVector target, boolean weight) {
PVector steer = new PVector(); //creates vector for steering
steer.set(PVector.sub(pos, target)); //steering vector points away from target
if (weight) steer.mult(1/sq(PVector.dist(pos, target)));
//steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
return steer;
}
PVector attract(PVector target, boolean weight) {
PVector steer = new PVector(); //creates vector for steering
steer.set(PVector.sub(target, pos)); //steering vector points away from target
if (weight) steer.mult(1/sq(PVector.dist(target, pos)));
//steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
return steer;
}
PVector bounce(PVector target, boolean weight) {
PVector steer = new PVector(); //creates vector for steering
steer.set(PVector.sub(pos, target)); //steering vector points away from target
if (weight) steer.mult(1/sq(PVector.dist(pos, target)));
//steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
return steer;
}
PVector seperation(ArrayList boids) {
PVector posSum = new PVector(0, 0);
PVector repulse;
for (int i=0; i<boids.size (); i++) {
Boid b = (Boid)boids.get(i);
float d = PVector.dist(pos, b.pos);
if (d>0&&d<=neighborhoodRadius) {
repulse = PVector.sub(pos, b.pos);
repulse.normalize();
repulse.div(d);
posSum.add(repulse);
}
}
return posSum;
}
PVector alignment(ArrayList boids) {
PVector velSum = new PVector(0, 0);
int count = 0;
for (int i=0; i<boids.size (); i++) {
Boid b = (Boid)boids.get(i);
float d = PVector.dist(pos, b.pos);
if (d>0&&d<=neighborhoodRadius) {
velSum.add(b.vel);
count++;
}
}
if (count>0) {
velSum.div((float)count);
velSum.limit(maxSteerForce);
}
return velSum;
}
PVector cohesion(ArrayList boids) {
PVector posSum = new PVector(0, 0);
PVector steer = new PVector(0, 0);
int count = 0;
for (int i=0; i<boids.size (); i++) {
Boid b = (Boid)boids.get(i);
float d = dist(pos.x, pos.y, b.pos.x, b.pos.y);
if (d>0&&d<=neighborhoodRadius) {
posSum.add(b.pos);
count++;
}
}
if (count>0) posSum.div((float)count);
steer = PVector.sub(posSum, pos);
steer.limit(maxSteerForce);
return steer;
}
}
class BoidList {
ArrayList boids; //will hold the boids in this BoidList
float h; //for color
BoidList(int n, float ih, int xstart, int ystart) {
boids = new ArrayList();
h = ih;
for (int i=0; i<n; i++) {
boids.add(new Boid(new PVector(xstart, ystart)));
}
}
void run() {
for (int i=0; i<boids.size (); i++) {
Boid tempBoid = (Boid)boids.get(i); //create a temporary boid to process and make it the current boid in the list
tempBoid.h = h;
tempBoid.run(boids); //tell the temporary boid to execute its run method
}
}
}

My program is storing my array backwards

I'm using a program called "Processing" to write this code. The code is supposed to record mouse coordinates in an array when u drag your mouse, and then when you release your mouse, it will show a circle following the path of the coordinates stored in the array, but right now it plays the circle from when I stopped dragging my mouse, to where i started dragging. This is supposed to be the other way around, but I've tried a lot of get it the reverse, but nothing I do seems to work :/
If you could show me it would be really helpful! I'm sure I missed something really obvious.
int num = 100;
int[] x = new int[num];
int[] y = new int[num];
boolean released = false;
int arrayIndex;
boolean drag = false;
void setup() {
size(600, 600);
noStroke();
smooth();
fill(255, 102);
}
void draw() {
background(0);
if (released==true){
arrayIndex= (arrayIndex+1)%100;
ellipse(x[arrayIndex],y[arrayIndex],20,20);
}
}
void mouseDragged(){
drag=true;
x[0] = mouseX;
y[0] = mouseY;
for (int i = num - 1; i > 0; i--) {
x[i] = x[i-1];
y[i] = y[i-1];
}
}
void mouseReleased(){
released=true;
}
As pointed you add coordinates from end to begin and read form begin to end. So reverse the display iteration, eithr by using frameCount, or a intermediary var...
using frameCount:
int num = 100;
int[] x = new int[num];
int[] y = new int[num];
boolean released = false;
int arrayIndex;
boolean drag = false;
void setup() {
size(600, 600);
noStroke();
smooth();
fill(255, 102);
}
void draw() {
background(0);
if (released==true){
arrayIndex= (num-1) - (frameCount+1)%100;
ellipse(x[arrayIndex],y[arrayIndex],20,20);
}
}
void mouseDragged(){
drag=true;
x[0] = mouseX;
y[0] = mouseY;
for (int i = num - 1; i > 0; i--) {
x[i] = x[i-1];
y[i] = y[i-1];
}
}
void mouseReleased(){
released=true;
}
using another var:
int num = 100;
int[] x = new int[num];
int[] y = new int[num];
boolean released = false;
int arrayIndex;
boolean drag = false;
void setup() {
size(600, 600);
noStroke();
smooth();
fill(255, 102);
}
void draw() {
background(0);
if (released==true){
arrayIndex= (arrayIndex+1)%100;
int reversed = (num-1) - arrayIndex;
ellipse(x[reversed],y[reversed],20,20);
}
}
void mouseDragged(){
drag=true;
x[0] = mouseX;
y[0] = mouseY;
for (int i = num - 1; i > 0; i--) {
x[i] = x[i-1];
y[i] = y[i-1];
}
}
void mouseReleased(){
released=true;
}

Program built using Unity3D Freezing PC - Sporadic

My program that I built using Unity3D sporadically freezes, and this action freezes my computer. I'm unable to pinpoint the root cause. I had placed logs all over my project, but the game failed to freeze.
Has any Unity3D developer experience their apps sporadically freeze in the manner in which I am describing? Does anyone have any ideas or suggestions?
Due to a 30K character limit, the below object has been modified slightly. This is the object I believe contains a flaw, but I am unable to identify this flaw.
public class gamePlayController : MonoBehaviour {
void Start () {
int i = 0;
int selectedPlayers = PlayerPrefs.GetInt("TotalPlayers");
foreach( GameObject touchable in GameObject.FindGameObjectsWithTag("Touchable") )
{
touchable.SetActive(false);
touchable.AddComponent(typeof(PlayerCollisionDispatcher));
PlayerCollisionDispatcher nextDispatcher = touchable.GetComponent<PlayerCollisionDispatcher>();
nextDispatcher.currentGameObject = touchable;
nextDispatcher.gameObject.AddComponent("AudioSource");
for(i = 0; i < this.m_Players.Count; i++)
{
if(string.Compare(touchable.name, this.m_Players[i].name) < 0)
{
break;
}
}
if(i < this.m_Players.Count)
{
this.m_Players.Insert(i, touchable);
}
else
{
this.m_Players.Add(touchable);
}
}
while(this.m_Players.Count > selectedPlayers)
{
this.m_Players.RemoveRange(selectedPlayers, this.m_Players.Count - selectedPlayers);
}
this.restartGame();
}
void OnGameTimer(object sender, ElapsedEventArgs e)
{
}
void Update() {
Vector3 vector = m_ArialCamera.camera.transform.position;
vector.x = Mathf.Abs((1500 * this.m_ArialView.x) - 1500) + 250;
vector.y = (600 * this.m_ArialView.y) + 100;
vector.z = (1500 * this.m_ArialView.z) + 250;
m_ArialCamera.camera.transform.position = vector;
if(this.m_IsGameOver)
{
Application.LoadLevel("Replay Screen");
}
else if(this.m_SimulateCamera)
{
this.SimulateCamera();
}
else if(m_AutoPluck)
{
this.AutoPluck();
}
else if(Time.timeScale != 0.0f && this.m_Dispatcher && this.m_Dispatcher.didObjectStop)
{
this.determineTurnOutcome();
}
else if(Time.timeScale != 0.0f && this.m_Dispatcher && this.m_Dispatcher.didObjectMove)
{
this.m_Dispatcher.trackMovementProgress();
}
else if(Time.timeScale != 0.0f && this.m_Dispatcher
&& this.m_Players[this.m_PlayerIndex].rigidbody.velocity.magnitude > 15.0f
&& this.m_Dispatcher.didPluck)
{
this.m_Dispatcher.didObjectMove = true;
}
}
void restartGame()
{
this.m_PlayerIndex = -1;
foreach( GameObject touchable in this.m_Players)
{
GameObject startField = GameObject.FindWithTag ("StartField");
touchable.SetActive(false);
touchable.rigidbody.useGravity = false;
touchable.rigidbody.velocity = Vector3.zero;
touchable.rigidbody.AddForce(Vector3.zero);
touchable.rigidbody.AddTorque(Vector3.zero);
if(startField)
{
Vector3 nextPoint = startField.renderer.bounds.center;
nextPoint.y = 11.0f;
touchable.transform.position = nextPoint;
}
touchable.rigidbody.useGravity = true;
}
this.startNextPlayer();
}
void startNextPlayer()
{
bool isActivePlayerReady = true;
do{
if(this.m_PlayerIndex != -1)
{
audioPlayer.PlayAudio("Audio/Next Player");
}
this.m_PlayerIndex = (this.m_PlayerIndex + 1)%this.m_Players.Count;
this.m_Dispatcher = this.m_Players[this.m_PlayerIndex].GetComponent<PlayerCollisionDispatcher>();
if(this.m_Dispatcher && !this.m_Dispatcher.isGameOver && !this.m_Dispatcher.didEnterMud)
{
if(!this.m_Players[this.m_PlayerIndex].activeSelf)
{
this.m_Dispatcher.startGame();
this.m_Players[this.m_PlayerIndex].SetActive(true);
}
this.m_Dispatcher.startTurn();
}
}
while(!isActivePlayerReady);
Vector3 vector = this.m_Players[this.m_PlayerIndex].transform.position;
vector.x = (1500 * this.m_ArialView.x) + 250;
vector.y = 300;
vector.z = (1500 * this.m_ArialView.z) + 250;
m_ArialCamera.camera.transform.position = vector;
this.setAnnouncement("Player " + this.m_Players[this.m_PlayerIndex].name + "'s Turn");
if(this.m_PlayerIndex != 0)
{
this.m_IsSimulating = PlayerPrefs.GetInt("SimulatePlayer" + this.m_Players[this.m_PlayerIndex].name);
this.m_IsSimulating = 1;
}
else
{
this.m_IsSimulating = 0;
}
GameObject mainCamera = GameObject.FindWithTag ("MainCamera");
MouseOrbit mo = null;
if(mainCamera)
{
mo = mainCamera.GetComponent<MouseOrbit>();
}
if(this.m_IsSimulating >= 1)
{
this.StartSimulation();
if(mo)
{
mo.DoFreeze = true;
}
}
else
{
if(mo)
{
mo.DoFreeze = false;
}
}
}
void StartSimulation()
{
System.Random random = new System.Random();
StringBuilder sb = new StringBuilder();
int randomNumber = 0;
//determine either the player object or the next block
if(this.m_Dispatcher.isKiller)
{
m_SimulateToObject = this.m_Players[randomNumber%this.m_Players.Count];
randomNumber = random.Next(0, 100);
}
else
{
sb.AppendFormat("{0:D2}", this.m_Dispatcher.targetScore);
Debug.Log("target score=" + sb.ToString());
foreach(GameObject scoreField in GameObject.FindGameObjectsWithTag("ScoreField"))
{
if(scoreField.name == sb.ToString())
{
m_SimulateToObject = scoreField;
break;
}
}
}
this.m_IsTargetInitiallyVisible = false;
this.m_SimulationTimer = new System.Timers.Timer();
this.m_SimulationTimer.Elapsed+=new ElapsedEventHandler(TriggerCameraSimulation);
this.m_SimulationTimer.Interval=2500;
this.m_SimulationTimer.Enabled=true;
}
void TriggerCameraSimulation(object sender, ElapsedEventArgs e)
{
this.m_SimulationTimer.Enabled = false;
this.m_SimulationTimer.Dispose();
this.m_SimulateCamera = true;
}
void SimulateCamera()
{
GameObject mainCamera = GameObject.FindWithTag ("MainCamera");
MouseOrbit mo = null;
this.m_SimulationTimer.Enabled = false;
this.m_SimulationTimer.Dispose();
if(mainCamera)
{
mo = mainCamera.GetComponent<MouseOrbit>();
if(!this.m_IsTargetInitiallyVisible)
{
mo.IsManualMove = true;
mainCamera.transform.position = this.m_Players[this.m_PlayerIndex].transform.position;
mainCamera.transform.LookAt(this.m_SimulateToObject.transform, Vector3.up);
this.m_IsTargetInitiallyVisible = true;
}
else if(this.m_SimulateCamera)
{
if(mo.getDistance() >= 10.0f)
{
this.m_SimulateCamera = false;
}
mo.setDistance(-0.001f);
}
}
if(!this.m_SimulateCamera)
{
this.m_SimulationTimer = new System.Timers.Timer();
this.m_SimulationTimer.Elapsed+=new ElapsedEventHandler(TriggerSimulatedPluck);
this.m_SimulationTimer.Interval=2000;
this.m_SimulationTimer.Enabled=true;
}
}
void TriggerSimulatedPluck(object sender, ElapsedEventArgs e)
{
this.m_SimulationTimer.Enabled = false;
this.m_SimulationTimer.Dispose();
this.m_AutoPluck = true;
}
void AutoPluck()
{
System.Random random = new System.Random();
GameObject mainCamera = GameObject.FindWithTag ("MainCamera");
MouseOrbit mo = null;
float applyForce = 0.0f;
float slope = 0.00028648399272739457f;
float y_int = 0.2908366193449838f;
Vector3 vTorque = Vector3.zero;
int simulateId = PlayerPrefs.GetInt("SimulatePlayer" + this.m_Players[this.m_PlayerIndex].name);
int seed = (5 * ((int)(SimulationOptions.Pro) - simulateId));
int xSeed = 0;
int ySeed = 0;
int zSeed = 0;
int sign = random.Next(1, 1000)%2;
int range = random.Next(1, 1000)%seed;
int myValue = 0;
this.m_SimulationTimer.Enabled = false;
this.m_SimulationTimer.Dispose();
if(mainCamera)
{
mo = mainCamera.GetComponent<MouseOrbit>();
mo.IsManualMove = false;
}
this.m_AutoPluck = false;
if(simulateId >= 1)
{
float distance = Vector3.Distance(this.m_Players[this.m_PlayerIndex].transform.position,
this.m_SimulateToObject.transform.position);
if(simulateId != (int)(SimulationOptions.Pro))
{
myValue = random.Next(1, 6);
seed = (int)(myValue * ((int)(SimulationOptions.Pro) - simulateId));
sign = random.Next(1, 2);
range = random.Next(1, seed);
if(random.Next(1, 1000)%3 == 0)
{
distance += (sign == 1 ? range : -range);
}
}
vTorque.x = (float)(random.Next(1, 90));
vTorque.y = (float)(random.Next(1, 90));
vTorque.z = (float)(random.Next(1, 90));
applyForce = (slope * distance) + y_int;
this.m_Dispatcher.pluckObject(applyForce, vTorque);
}
}
void determineTurnOutcome()
{
int number = -1;
bool canActivePlayerContinue = false;
bool isAutoReward = false;
bool didElinimatePlayer = false;
foreach(GameObject nextObject in this.m_Players)
{
PlayerCollisionDispatcher nextDispatcher = nextObject.GetComponent<PlayerCollisionDispatcher>();
if(nextObject.activeSelf && !nextDispatcher.isGameOver && !nextDispatcher.isActive)
{
if(nextDispatcher.currentScore == nextDispatcher.targetScore)
{
nextDispatcher.totalScore = nextDispatcher.targetScore;
int.TryParse(nextDispatcher.name, out number);
nextDispatcher.targetScore++;
if(nextDispatcher.totalScore >= 13 || nextDispatcher.targetScore > 13)
{
nextDispatcher.totalScore = 13;
nextDispatcher.targetScore = 13;
nextDispatcher.isKiller = true;
this.setMaterial(nextDispatcher.renderer, "killers", nextDispatcher.name);
}
else
{
this.setMaterial(nextDispatcher.renderer, "numbers", nextDispatcher.name);
}
}
else if(nextDispatcher.didKillerCollide && (nextDispatcher.didLeaveBoard || nextDispatcher.didLeaveBounds))
{
this.setMaterial(nextDispatcher.renderer, "eliminated", nextDispatcher.name);
nextDispatcher.isGameOver = true;
didElinimatePlayer = true;
}
else if(nextDispatcher.didPlayerCollide && (nextDispatcher.didLeaveBoard || nextDispatcher.didLeaveBounds))
{
if(int.TryParse(nextDispatcher.name, out number))
{
nextDispatcher.targetScore = 1;
nextDispatcher.totalScore = 0;
}
}
else if(nextDispatcher.didEnterMud)
{
this.setMaterial(nextDispatcher.renderer, "mudd", nextDispatcher.name);
nextDispatcher.isKiller = false;
}
else if(nextDispatcher.isInMud && !nextDispatcher.didEnterMud)
{
isAutoReward = true;
}
else
{
this.setMaterial(nextDispatcher.renderer, "numbers", nextDispatcher.name);
}
}
nextDispatcher.transferStates();
}
if(this.m_Dispatcher.isKiller && !didElinimatePlayer)
{
this.setMaterial(this.m_Dispatcher.renderer, "numbers", this.m_Dispatcher.name);
this.m_Dispatcher.totalScore = 0;
this.m_Dispatcher.targetScore = 1;
this.m_Dispatcher.isKiller = false;
}
else if(this.m_Dispatcher.didEnterMud)
{
this.setMaterial(this.m_Dispatcher.renderer, "mud", this.m_Dispatcher.name);
}
else if(this.m_Dispatcher.currentScore == this.m_Dispatcher.targetScore || isAutoReward)
{
this.m_Dispatcher.totalScore = this.m_Dispatcher.targetScore;
canActivePlayerContinue = true;
this.m_Dispatcher.consecutivePops++;
int.TryParse(this.m_Dispatcher.name, out number);
this.m_Dispatcher.targetScore++;
this.setMaterial(this.m_Dispatcher.renderer, "numbers", this.m_Dispatcher.name);
}
else
{
this.setMaterial(this.m_Dispatcher.renderer, "numbers", this.m_Dispatcher.name);
}
this.isWinnerAnnounced();
if(!this.m_IsGameOver && !canActivePlayerContinue)
{
this.m_Dispatcher.endTurn();
this.startNextPlayer();
}
else if(canActivePlayerContinue)
{
this.m_Dispatcher.transferStates();
this.m_Dispatcher.isActive = true;
this.m_Dispatcher.didObjectMove = false;
this.m_Dispatcher.didObjectStop = false;
if(this.m_IsSimulating >= 1)
{
this.StartSimulation();
}
}
this.m_ForceValue = 0.0f;
}
void isWinnerAnnounced()
{
StringBuilder sb = new StringBuilder();
int totalPlayers = 0;
string winner = string.Empty;
int number = -1;
int totalPlayersInMud = 0;
foreach(GameObject nextObject in this.m_Players)
{
PlayerCollisionDispatcher nextDispatcher = nextObject.GetComponent<PlayerCollisionDispatcher>();
if(!nextDispatcher.isGameOver)
{
totalPlayers++;
winner = nextObject.name;
}
if(nextDispatcher.isInMud)
{
totalPlayersInMud++;
}
}
if(totalPlayers == 1)
{
if(winner != string.Empty && int.TryParse(winner, out number))
{
sb.AppendFormat("Congratulations Player {0}", number);
PlayerPrefs.SetString("WinningPlayer", sb.ToString());
}
else
{
PlayerPrefs.SetString("WinningPlayer", "Congratulations");
}
this.m_IsGameOver = true;
}
else if(totalPlayersInMud == this.m_Players.Count)
{
PlayerPrefs.SetString("WinningPlayer", "All players are stuck in the mud!");
this.m_IsGameOver = true;
}
}
void setMaterial(Renderer renderer, string state, string playerId)
{
StringBuilder sbNextImage = new StringBuilder();
sbNextImage.AppendFormat("Materials/playerObjects/{0}/{1}", state, playerId);
Material newMat = Resources.Load(sbNextImage.ToString(), typeof(Material)) as Material;
if(newMat)
{
renderer.material = newMat;
}
else
{
Debug.Log("FAILED to set material: " + sbNextImage.ToString());
}
}
void setAnnouncement(string text)
{
this.m_IsAnnouncement = true;
this.m_AnnouncementHeight = (int)(Screen.height * 0.5);
this.m_AnnouncementText = text;
}
void OnGUI() {
GUIStyle labelStyle = GUI.skin.label;
int number = -1;
StringBuilder scoreDetails = new StringBuilder();
StringBuilder turnDetails = new StringBuilder();
float x = 0;
float y = 0;
float w = 64.0f;
float h = 32.0f;
float alpha = 1.0f;
if(this.m_IsAnnouncement)
{
this.displayAnnouncement();
}
labelStyle.normal.textColor = new Color(1.0f, 1.0f, 1.0f, alpha);
Texture2D texture = new Texture2D(32, 32, TextureFormat.ARGB32, false);
for(int i = 0; i < 32; i++)
{
for(int j = 0; j < 32; j++)
{
texture.SetPixel(i, j, new Color(0.0f, 0.0f, 0.0f, 0.25f));
}
}
texture.Apply();
labelStyle.normal.background = texture;
if(this.m_DoShowScore)
{
foreach(GameObject nextObject in this.m_Players)
{
PlayerCollisionDispatcher nextDispatcher = nextObject.GetComponent<PlayerCollisionDispatcher>();
int.TryParse(nextDispatcher.name, out number);
if(nextDispatcher.isGameOver)
{
scoreDetails.AppendFormat("\tPlayer {0}: Game Over\n", number);
}
else if(nextDispatcher.didEnterMud)
{
scoreDetails.AppendFormat("\tPlayer {0}: In The Mudd\n", number);
}
else if(nextDispatcher.isKiller)
{
scoreDetails.AppendFormat("\tPlayer {0}: Killer\n", number);
}
else
{
scoreDetails.AppendFormat("\tPlayer {0}: {1}\n", number, nextDispatcher.totalScore);
}
}
GUI.Label (new Rect (0, 0, 225, 100), scoreDetails.ToString());
}
w = 64.0f;
h = 32.0f;
x = Screen.width - w;
y = Screen.height - h;
if(GUI.Button (new Rect (x, y, w, h), "Menu"))
{
audioPlayer.PlayAudio("Audio/Click");
this.m_IsMenuShowing = !this.m_IsMenuShowing;
}
if(this.m_IsMenuShowing)
{
w = (64.0f * this.m_MenuText.Length);
h = 32.0f;
x = Screen.width - w - 64.0f;
y = Screen.height - h;
int selOption = GUI.Toolbar(new Rect(x, y, w, h), this.m_MenuOption, this.m_MenuText);
if(selOption != this.m_MenuOption)
{
audioPlayer.PlayAudio("Audio/Click");
this.m_MenuOption = -1;
this.m_IsMenuShowing = !this.m_IsMenuShowing;
switch(selOption)
{
case (int)(MenuOptions.ArialViewOption): //arial
this.m_ArialCamera.SetActive(!this.m_ArialCamera.activeSelf);
break;
case (int)(MenuOptions.VolumeOption): //mute
int muteVolume = PlayerPrefs.GetInt("MuteVolume");
muteVolume = (muteVolume + 1)%2;
PlayerPrefs.SetInt("MuteVolume", muteVolume);
if(muteVolume == 0)
{
this.m_MenuText[(int)(MenuOptions.VolumeOption)] = "Mute";
}
else
{
this.m_MenuText[(int)(MenuOptions.VolumeOption)] = "Volume";
}
break;
case (int)(MenuOptions.PauseOption): //pause
if(Time.timeScale == 0.0f)
{
this.setAnnouncement("Continuing Game Play");
Time.timeScale = this.m_Speed;
this.m_MenuText[(int)(MenuOptions.PauseOption)] = "Pause";
}
else
{
this.setAnnouncement("Game Is Paused");
Time.timeScale = 0.0f;
this.m_MenuText[(int)(MenuOptions.PauseOption)] = "Play";
}
break;
case (int)(MenuOptions.ScoresOption): //scores
this.m_DoShowScore = !this.m_DoShowScore;
break;
case (int)(MenuOptions.RestartOption): //restart
Time.timeScale = this.m_Speed;
this.restartGame();
break;
case (int)(MenuOptions.QuitOption): //quit
Application.LoadLevel("Opening Screen");
break;
default:
break;
}
}
}
if(this.m_ArialCamera.activeSelf)
{
x = Screen.width * 0.7f - 10.0f;
y = 0;
w = 10.0f;
h = Screen.height * 0.3f;
this.m_ArialView.z = GUI.VerticalSlider (new Rect(x, y, w, h), this.m_ArialView.z, 1.0f, 0.0f);
x = Screen.width * 0.7f;
y = Screen.height * 0.3f;
w = Screen.width * 0.3f;
h = 10.0f;
this.m_ArialView.x = GUI.HorizontalSlider (new Rect(x, y, w, h), this.m_ArialView.x, 1.0f, 0.0f);
x = Screen.width * 0.7f;
y = Screen.height * 0.3f + 12.0f;
w = Screen.width * 0.3f;
h = 10.0f;
this.m_ArialView.y = GUI.HorizontalSlider (new Rect(x, y, w, h), this.m_ArialView.y, 1.0f, 0.0f);
}
int.TryParse(this.m_Players[this.m_PlayerIndex].name, out number);
turnDetails.AppendFormat("\tPlayer {0}'s Turn\n", number);
turnDetails.AppendFormat("\tNext Goal: {0}\n", this.m_Dispatcher.targetScore);
GUI.Label (new Rect (0, Screen.height - 100, 225, 100), turnDetails.ToString());
if(!this.m_Dispatcher.didObjectMove && m_IsSimulating == 0)
{
x = 250.0f;
y = Screen.height - 190.0f;
w = 30.0f;
h = 150.0f;
this.m_ForceValue = GUI.VerticalSlider (new Rect(x, y, w, h), m_ForceValue, 1.0f, 0.0f);
x = 250.0f;
y = Screen.height - 30.0f;
w = 100.0f;
h = 30.0f;
if(GUI.Button (new Rect(x, y, w, h), "Pluck!"))
{
System.Random random = new System.Random();
Vector3 vTorque = Vector3.zero;
int xSeed = 0;
int ySeed = 0;
int zSeed = 0;
xSeed = (random.Next(1, 45));
ySeed = (random.Next(1, 45));
zSeed = (random.Next(1, 45));
vTorque = new Vector3(xSeed, ySeed, zSeed);
this.m_Dispatcher.pluckObject(this.m_ForceValue, vTorque);
}
}
}
void displayAnnouncement()
{
float x = 0;
float y = 0;
float w = 0;
float h = 0;
float alpha = 1.0f;
GUIStyle announcementStyle = null;
GUIStyle labelStyle = null;
announcementStyle = new GUIStyle();
labelStyle = GUI.skin.label;
labelStyle.normal.textColor = new Color(1.0f, 1.0f, 1.0f, alpha);
x = (int)(Screen.width * 0.25);
y = (int)m_AnnouncementHeight;
w = (int)(Screen.width * 0.5);
h = 100;
alpha = (float)m_AnnouncementHeight/(float)(Screen.height * 0.5);
announcementStyle.fontSize = 32;
announcementStyle.alignment = TextAnchor.MiddleCenter;
announcementStyle.fontStyle = FontStyle.BoldAndItalic;
announcementStyle.normal.textColor = new Color(1.0f, 1.0f, 1.0f, alpha);
GUI.Label (new Rect (x, y, w, h), this.m_AnnouncementText, announcementStyle);
if(Time.timeScale != 0.0f)
{
if((this.m_AnnouncementHeight + h) <= 0)
{
this.m_IsAnnouncement = false;
this.m_AnnouncementHeight = (int)(Screen.height * 0.5);
}
else
{
this.m_AnnouncementHeight -= 1;
}
}
}
}
-----------
I believe I have narrowed the freezing down. Simulated testing results is leading me to believe that my problem is inside the OnGUI() method. I have commented that method out all together, and my app is operating smoothly. I'll figure this out, unless someone beats me to the root cause and solution.
I solved it...
My initial suspicions were correct: the problem did lie within the OnGUI() method. I moved the following source code to the Start() method. It made sense, since I'm only building a transparent background texture once.:
Texture2D texture = new Texture2D(32, 32, TextureFormat.ARGB32, false);
for(int i = 0; i < 32; i++)
{
for(int j = 0; j < 32; j++)
{
texture.SetPixel(i, j, new Color(0.0f, 0.0f, 0.0f, 0.25f));
}
}
texture.Apply();

how to get the visible area of canvas in wpf

I am creating an application just like a paint in WPF, and I want to add zoom functionality to it. I am taking canvas as a parent and writable bitmap on it as child on which I draw. When the size of the canvas is small, I am drawing on writable bitmap smoothly, but when the size of the canvas is large, and zoom it, canvas size will be large, problem occur to draw on this large area. So I want to find the visible region of the canvas so that I can draw on it smoothly.
Please give me a source code to find the visible region of the canvas.
I have create this application:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Interop;
namespace MapDesigner.Controls
{
class MapCanvas : Canvas
{
#region Routed Events
public static readonly RoutedEvent SelectedColorChangeEvent = EventManager.RegisterRoutedEvent(
"SelectedColorChange", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ucToolBox));
public event RoutedEventHandler SelectedColorChange
{
add { AddHandler(SelectedColorChangeEvent, value); }
remove { RemoveHandler(SelectedColorChangeEvent, value); }
}
#endregion
#region Enums
public enum Tool
{
Pencil,
FloodFill,
Eraser,
RectSelect,
Brush,
Part
}
#endregion
WriteableBitmap _wBMP;
Image _dispImg = new Image();
ScaleTransform st = new ScaleTransform();
int canvasHeight, canvasWidth;
double zoomLevel = 1;
Border brdGrid = new Border();
Color cellColor = Colors.Black;
Tool currentTool = Tool.Pencil;
int[,] array;
bool drawing = false;
bool showGrids = true;
public TextBlock tbPos;
public Tool CurrentTool
{
get
{
return currentTool;
}
set
{
currentTool = value;
}
}
public Color CellColor
{
get
{
return cellColor;
}
set
{
cellColor = value;
}
}
public bool GridsVisible
{
get
{
return showGrids;
}
set
{
showGrids = value;
}
}
public MapCanvas()
{
this.Children.Clear();
this.Children.Add(_dispImg);
//st.ScaleX = 1;
//st.ScaleY = 1;
// this.LayoutTransform = st;
}
void Refresh()
{
//canvas = new MapCanvas();
this.Children.Clear();
this.Children.Add(_dispImg);
st.ScaleX = 1;
st.ScaleY = 1;
this.Height = 0;
this.Width = 0;
zoomLevel = 1;
drawing = false;
}
public void LoadBMP(Uri bmpUri)
{
Refresh();
BitmapImage bmi = new BitmapImage(bmpUri);
_wBMP = new WriteableBitmap(bmi);
_dispImg.Source = _wBMP;
this.Height = bmi.Height;
this.Width = bmi.Width;
ShowGrids();
}
public void CreateBMP(int width, int height)
{
Refresh();
_wBMP = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr32, BitmapPalettes.WebPalette);
_wBMP.setPixel(Colors.White);
_dispImg.Source = _wBMP;
this.Height = height;
this.Width = width;
ShowGrids();
}
public void CreateNewDesign(Size mapSize)
{
Refresh();
_wBMP = new WriteableBitmap((int)mapSize.Width, (int)mapSize.Width, 96, 96, PixelFormats.Bgr32, BitmapPalettes.WebPalette);
_wBMP.setPixel(Colors.White);
_dispImg.Source = _wBMP;
array = new int[(_wBMP.PixelHeight + 1), (_wBMP.PixelWidth + 1)];
canvasWidth = (int)mapSize.Width;
canvasHeight = (int)mapSize.Height;
this.Height = mapSize.Height;
this.Width = mapSize.Width;
ShowGrids();
}
void ShowGrids()
{
return;
double width = 1;// _tileWidth + _tileMargin;
double height = 1;// _tileHeight + _tileMargin;
double numTileToAccumulate = 16;
Polyline gridCell = new Polyline();
gridCell.Margin = new Thickness(.5);
gridCell.Stroke = Brushes.LightBlue;
gridCell.StrokeThickness = 0.1;
gridCell.Points = new PointCollection(new Point[] { new Point(0, height-0.1),
new Point(width-0.1, height-0.1), new Point(width-0.1, 0) });
VisualBrush gridLines = new VisualBrush(gridCell);
gridLines.TileMode = TileMode.Tile;
gridLines.Viewport = new Rect(0, 0, 1.0 / numTileToAccumulate, 1.0 / numTileToAccumulate);
gridLines.AlignmentX = AlignmentX.Center;
gridLines.AlignmentY = AlignmentY.Center;
VisualBrush outerVB = new VisualBrush();
Rectangle outerRect = new Rectangle();
outerRect.Width = 10.0; //can be any size
outerRect.Height = 10.0;
outerRect.Fill = gridLines;
outerVB.Visual = outerRect;
outerVB.Viewport = new Rect(0, 0,
width * numTileToAccumulate, height * numTileToAccumulate);
outerVB.ViewportUnits = BrushMappingMode.Absolute;
outerVB.TileMode = TileMode.Tile;
this.Children.Remove(brdGrid);
brdGrid = new Border();
brdGrid.Height = this.Height;
brdGrid.Width = this.Width;
brdGrid.Background = outerVB;
this.Children.Add(brdGrid);
}
protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
{
base.OnMouseMove(e);
tbPos.Text = (_wBMP.PixelWidth / zoomLevel).ToString() + "," + (_wBMP.PixelHeight / zoomLevel).ToString() + " | " + Math.Ceiling((((Point)e.GetPosition(this)).X) / zoomLevel).ToString() + "," + Math.Ceiling((((Point)e.GetPosition(this)).Y / zoomLevel)).ToString();
if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
{
Point pos = e.GetPosition(this);
int xPos = (int)Math.Ceiling((pos.X) / zoomLevel);
int yPos = (int)Math.Ceiling((pos.Y) / zoomLevel);
int xDraw = (int)Math.Ceiling(pos.X);
int yDraw = (int)Math.Ceiling(pos.Y);
array[xPos, yPos] = 1;
drawing = true;
SetPixelsFromArray((int)zoomLevel);
//for (int i = 0; i < zoomLevel; i++)
//{
// for (int j = 0; j < zoomLevel; j++)
// {
// _wBMP.setPixel(xDraw, yDraw, cellColor);
// _dispImg.Source = _wBMP;
// }
//}
//_wBMP.setPixel(xPos, yPos, cellColor);
//_wBMP.setPixel((int)pos.X, (int)pos.Y, cellColor);
//_dispImg.Source = _wBMP;
}
}
private void SetPixelsFromArray(int ZoomLevel)
{
for (int i = 1; i < _wBMP.PixelWidth / ZoomLevel; i++)
{
for (int j = 1; j < _wBMP.PixelHeight / ZoomLevel; j++)
{
if (array[i, j] == 1)
{
for (int k = 0; k < ZoomLevel; k++)
{
for (int l = 0; l < ZoomLevel; l++)
{
_wBMP.setPixel((int)(i * ZoomLevel + k), (int)(j * ZoomLevel + l), cellColor);
_dispImg.Source = _wBMP;
}
}
}
}
}
}
protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e)
{
//double d= this.ActualHeight;
//Double t =(double) this.GetValue(Canvas.TopProperty);
//double i = Convert.ToDouble(top);
getScreenRect();
if (e.ChangedButton == System.Windows.Input.MouseButton.Right)
{
if (cellColor == Colors.Black)
{
cellColor = Colors.Red;
}
else
{
cellColor = Colors.Black;
}
}
else if (e.ChangedButton == System.Windows.Input.MouseButton.Left)
{
Point pos = e.GetPosition(this);
int xPos = (int)Math.Ceiling((pos.X) / zoomLevel);
int yPos = (int)Math.Ceiling((pos.Y) / zoomLevel);
array[xPos, yPos] = 1;
drawing = true;
SetPixelsFromArray((int)zoomLevel);
//_wBMP.setPixel((int)pos.X, (int)pos.Y, cellColor);
//_dispImg.Source = _wBMP;
}
}
private void getScreenRect()
{
Visual _rootVisual = HwndSource.FromVisual(this).RootVisual;
GeneralTransform transformToRoot = this.TransformToAncestor(_rootVisual);
Rect screenRect = new Rect(transformToRoot.Transform(new Point(0, 0)), transformToRoot.Transform(new Point(this.ActualWidth, this.ActualHeight)));
DependencyObject parent = VisualTreeHelper.GetParent(this);
while (parent != null)
{
Visual visual = parent as Visual;
System.Windows.Controls.Control control = parent as System.Windows.Controls.Control;
if (visual != null && control != null)
{
transformToRoot = visual.TransformToAncestor(_rootVisual);
Point pointAncestorTopLeft = transformToRoot.Transform(new Point(0, 0));
Point pointAncestorBottomRight = transformToRoot.Transform(new Point(control.ActualWidth, control.ActualHeight));
Rect ancestorRect = new Rect(pointAncestorTopLeft, pointAncestorBottomRight);
screenRect.Intersect(ancestorRect);
}
parent = VisualTreeHelper.GetParent(parent);
//}
// at this point screenRect is the bounding rectangle for the visible portion of "this" element
}
// return screenRect;
}
protected override void OnMouseWheel(System.Windows.Input.MouseWheelEventArgs e)
{
base.OnMouseWheel(e);
if (e.Delta > 0)
{
zoomLevel *= 2;
}
else
{
zoomLevel /= 2;
}
if (zoomLevel > 8)
{
zoomLevel = 8;
}
if (zoomLevel <= 1)
{
zoomLevel = 1;
// brdGrid.Visibility = Visibility.Collapsed;
}
else
{
//brdGrid.Visibility = Visibility.Visible;
}
_wBMP = new WriteableBitmap((int)zoomLevel * canvasWidth, (int)zoomLevel * canvasHeight, 96, 96, PixelFormats.Bgr32, BitmapPalettes.WebPalette);
_wBMP.setPixel(Colors.White);
this.Width = zoomLevel * canvasWidth;
this.Height = zoomLevel * canvasHeight;
if (drawing == true)
{
SetPixelsFromArray((int)zoomLevel);
}
//this.InvalidateVisual();
}
internal bool SaveAsBMP(string fileName)
{
return true;
}
}
public static class bitmapextensions
{
public static void setPixel(this WriteableBitmap wbm, Color c)
{
if (!wbm.Format.Equals(PixelFormats.Bgr32))
return;
wbm.Lock();
IntPtr buff = wbm.BackBuffer;
int Stride = wbm.BackBufferStride;
int x = 0;
int y = 0;
for (x = 0; x < wbm.PixelWidth; x++)
{
for (y = 0; y < wbm.PixelHeight; y++)
{
unsafe
{
byte* pbuff = (byte*)buff.ToPointer();
int loc = y * Stride + x * 4;
pbuff[loc] = c.B;
pbuff[loc + 1] = c.G;
pbuff[loc + 2] = c.R;
//pbuff[loc + 3] = c.A;
}
}
}
wbm.AddDirtyRect(new Int32Rect(0, 0, x, y));
wbm.Unlock();
}
public static void setPixel(this WriteableBitmap wbm, int x, int y, Color c)
{
if (y > wbm.PixelHeight - 1 || x > wbm.PixelWidth - 1)
return;
if (y < 0 || x < 0)
return;
if (!wbm.Format.Equals(PixelFormats.Bgr32))
return;
wbm.Lock();
IntPtr buff = wbm.BackBuffer;
int Stride = wbm.BackBufferStride;
unsafe
{
byte* pbuff = (byte*)buff.ToPointer();
int loc = y * Stride + x * 4;
pbuff[loc] = c.B;
pbuff[loc + 1] = c.G;
pbuff[loc + 2] = c.R;
//pbuff[loc + 3] = c.A;
}
wbm.AddDirtyRect(new Int32Rect(x, y, 1, 1));
wbm.Unlock();
}
public static Color getPixel(this WriteableBitmap wbm, int x, int y)
{
if (y > wbm.PixelHeight - 1 || x > wbm.PixelWidth - 1)
return Color.FromArgb(0, 0, 0, 0);
if (y < 0 || x < 0)
return Color.FromArgb(0, 0, 0, 0);
if (!wbm.Format.Equals(PixelFormats.Bgr32))
return Color.FromArgb(0, 0, 0, 0);
IntPtr buff = wbm.BackBuffer;
int Stride = wbm.BackBufferStride;
Color c;
unsafe
{
byte* pbuff = (byte*)buff.ToPointer();
int loc = y * Stride + x * 4;
c = Color.FromArgb(pbuff[loc + 3], pbuff[loc + 2], pbuff[loc + 1], pbuff[loc]);
}
return c;
}
}
}
You should implement IScrollInfo on your canvas (or actually, create a custom Panel that inherits from Canvas and implements IScrollInfo).
That interface holds all that is relevant to your situation:
http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.iscrollinfo.aspx
http://blogs.msdn.com/b/jgoldb/archive/2008/03/08/performant-virtualized-wpf-canvas.aspx

Resources